xref: /openbsd-src/sys/arch/octeon/dev/octeon_pcibus.c (revision b711551f3ad0c8a480c9d1297568b8616c06bdec)
1 /*	$OpenBSD: octeon_pcibus.c,v 1.23 2021/03/04 16:44:07 visa Exp $	*/
2 /*	$NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $	*/
3 /*	$NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $	*/
4 
5 /*
6  * Copyright (c) 2009, 2010 Miodrag Vallat.
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 /*-
21  * Copyright (c) 2001 The NetBSD Foundation, Inc.
22  * All rights reserved.
23  *
24  * This code is derived from software contributed to The NetBSD Foundation
25  * by Jason R. Thorpe.
26  *
27  * Redistribution and use in source and binary forms, with or without
28  * modification, are permitted provided that the following conditions
29  * are met:
30  * 1. Redistributions of source code must retain the above copyright
31  *    notice, this list of conditions and the following disclaimer.
32  * 2. Redistributions in binary form must reproduce the above copyright
33  *    notice, this list of conditions and the following disclaimer in the
34  *    documentation and/or other materials provided with the distribution.
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
37  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
38  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46  * POSSIBILITY OF SUCH DAMAGE.
47  */
48 
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/device.h>
52 #include <sys/extent.h>
53 #include <sys/malloc.h>
54 
55 #include <machine/autoconf.h>
56 #include <machine/bus.h>
57 #include <machine/intr.h>
58 #include <machine/octeonvar.h>
59 
60 #include <dev/pci/pcidevs.h>
61 #include <dev/pci/pcireg.h>
62 #include <dev/pci/pcivar.h>
63 #include <dev/pci/ppbreg.h>
64 
65 #include <octeon/dev/iobusvar.h>
66 #include <octeon/dev/octeon_pcibus.h>
67 
68 #include <uvm/uvm_extern.h>
69 
70 #ifdef DEBUG
71 #define OCTEON_PCIDEBUG(p) printf p
72 #else
73 #define OCTEON_PCIDEBUG(p)
74 #endif
75 
76 #define REG_READ32(addr)	(*(volatile uint32_t *)(addr))
77 #define REG_WRITE32(addr, data)	(*(volatile uint32_t *)(addr) = (uint32_t)(data))
78 
79 struct octeon_pcibus_softc {
80 	struct device sc_dev;
81 	struct mips_pci_chipset sc_pc;
82 	struct iobus_attach_args *sc_aa;
83 };
84 
85 int	octeon_pcibus_match(struct device *, void *, void *);
86 void	octeon_pcibus_attach(struct device *, struct device *, void *);
87 int	octeon_pcibus_print(void *, const char *);
88 
89 const struct cfattach pcibus_ca = {
90 	sizeof(struct octeon_pcibus_softc),
91 	octeon_pcibus_match, octeon_pcibus_attach
92 };
93 
94 struct cfdriver pcibus_cd = {
95 	NULL, "pcibus", DV_DULL
96 };
97 
98 bus_addr_t octeon_pcibus_pa_to_device(paddr_t);
99 paddr_t	octeon_pcibus_device_to_pa(bus_addr_t);
100 void	octeon_pcibus_attach_hook(struct device *, struct device *,
101 	    struct pcibus_attach_args *);
102 int	octeon_pcibus_bus_maxdevs(void *, int);
103 pcitag_t octeon_pcibus_make_tag(void *, int, int, int);
104 void	octeon_pcibus_decompose_tag(void *, pcitag_t, int *, int *, int *);
105 int	octeon_pcibus_pci_conf_size(void *, pcitag_t);
106 pcireg_t octeon_pcibus_pci_conf_read(void *, pcitag_t, int);
107 void	octeon_pcibus_pci_conf_write(void *, pcitag_t, int, pcireg_t);
108 int	octeon_pcibus_pci_intr_map(struct pci_attach_args *,
109 	    pci_intr_handle_t *);
110 const char *octeon_pcibus_pci_intr_string(void *, pci_intr_handle_t);
111 void	*octeon_pcibus_pci_intr_establish(void *, pci_intr_handle_t, int,
112 	    int (*)(void *), void *, char *);
113 void	octeon_pcibus_pci_intr_disestablish(void *, void *);
114 int	octeon_pcibus_intr_map(int dev, int fn, int pin);
115 int	octeon_pcibus_io_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
116 	    bus_space_handle_t *);
117 int	octeon_pcibus_mem_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
118 	    bus_space_handle_t *);
119 struct extent *octeon_pcibus_get_resource_extent(pci_chipset_tag_t, int);
120 
121 struct machine_bus_dma_tag octeon_pcibus_bus_dma_tag = {
122 	._cookie = NULL,
123 	._dmamap_create =	_dmamap_create,
124 	._dmamap_destroy =	_dmamap_destroy,
125 	._dmamap_load =		_dmamap_load,
126 	._dmamap_load_mbuf =	_dmamap_load_mbuf,
127 	._dmamap_load_uio =	_dmamap_load_uio,
128 	._dmamap_load_raw =	_dmamap_load_raw,
129 	._dmamap_load_buffer =	_dmamap_load_buffer,
130 	._dmamap_unload =	_dmamap_unload,
131 	._dmamap_sync =		_dmamap_sync,
132 	._dmamem_alloc =	_dmamem_alloc,
133 	._dmamem_free =		_dmamem_free,
134 	._dmamem_map =		_dmamem_map,
135 	._dmamem_unmap =	_dmamem_unmap,
136 	._dmamem_mmap =		_dmamem_mmap,
137 	._pa_to_device =	octeon_pcibus_pa_to_device,
138 	._device_to_pa =	octeon_pcibus_device_to_pa
139 };
140 
141 #define _OCTEON_PCIBUS_PCIIO_BASE	0x00001000
142 #define _OCTEON_PCIBUS_PCIIO_SIZE	0x08000000
143 #define _OCTEON_PCIBUS_PCIMEM_BASE	0x80000000
144 #define _OCTEON_PCIBUS_PCIMEM_SIZE	0x40000000
145 
146 struct mips_bus_space octeon_pcibus_pci_io_space_tag = {
147 	.bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIIO_BASE, CCA_NC),
148 	.bus_private = NULL,
149 	._space_read_1 =	generic_space_read_1,
150 	._space_write_1 =	generic_space_write_1,
151 	._space_read_2 =	generic_space_read_2,
152 	._space_write_2 =	generic_space_write_2,
153 	._space_read_4 =	generic_space_read_4,
154 	._space_write_4 =	generic_space_write_4,
155 	._space_read_8 =	generic_space_read_8,
156 	._space_write_8 =	generic_space_write_8,
157 	._space_read_raw_2 =	generic_space_read_raw_2,
158 	._space_write_raw_2 =	generic_space_write_raw_2,
159 	._space_read_raw_4 =	generic_space_read_raw_4,
160 	._space_write_raw_4 =	generic_space_write_raw_4,
161 	._space_read_raw_8 =	generic_space_read_raw_8,
162 	._space_write_raw_8 =	generic_space_write_raw_8,
163 	._space_map =		octeon_pcibus_io_map,
164 	._space_unmap =		generic_space_unmap,
165 	._space_subregion =	generic_space_region,
166 	._space_vaddr =		generic_space_vaddr
167 };
168 
169 struct mips_bus_space octeon_pcibus_pci_mem_space_tag = {
170 	.bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIMEM_BASE, CCA_NC),
171 	.bus_private = NULL,
172 	._space_read_1 =	generic_space_read_1,
173 	._space_write_1 =	generic_space_write_1,
174 	._space_read_2 =	generic_space_read_2,
175 	._space_write_2 =	generic_space_write_2,
176 	._space_read_4 =	generic_space_read_4,
177 	._space_write_4 =	generic_space_write_4,
178 	._space_read_8 =	generic_space_read_8,
179 	._space_write_8 =	generic_space_write_8,
180 	._space_read_raw_2 =	generic_space_read_raw_2,
181 	._space_write_raw_2 =	generic_space_write_raw_2,
182 	._space_read_raw_4 =	generic_space_read_raw_4,
183 	._space_write_raw_4 =	generic_space_write_raw_4,
184 	._space_read_raw_8 =	generic_space_read_raw_8,
185 	._space_write_raw_8 =	generic_space_write_raw_8,
186 	._space_map =		octeon_pcibus_mem_map,
187 	._space_unmap =		generic_space_unmap,
188 	._space_subregion =	generic_space_region,
189 	._space_vaddr =		generic_space_vaddr
190 };
191 
192 int
octeon_pcibus_match(struct device * parent,void * vcf,void * aux)193 octeon_pcibus_match(struct device *parent, void *vcf, void *aux)
194 {
195 	struct iobus_attach_args *aa = aux;
196 
197 	if ((octeon_boot_info->config_flags & BOOTINFO_CFG_FLAG_PCI_HOST) == 0) {
198 		OCTEON_PCIDEBUG(("%s, no PCI host function detected.\n", __func__));
199 		return 0;
200 	}
201 
202 	if (strcmp(aa->aa_name, pcibus_cd.cd_name) == 0)
203 		return 1;
204 
205 	return 0;
206 }
207 
208 void
octeon_pcibus_attach(struct device * parent,struct device * self,void * aux)209 octeon_pcibus_attach(struct device *parent, struct device *self, void *aux)
210 {
211 	struct octeon_pcibus_softc *sc;
212 	struct pcibus_attach_args pba;
213 
214 	sc = (struct octeon_pcibus_softc *)self;
215 	sc->sc_aa = aux;
216 
217 	printf("\n");
218 
219 	/*
220 	 * Attach PCI bus.
221 	 */
222 	sc->sc_pc.pc_attach_hook = octeon_pcibus_attach_hook;
223 	sc->sc_pc.pc_bus_maxdevs = octeon_pcibus_bus_maxdevs;
224 	sc->sc_pc.pc_make_tag = octeon_pcibus_make_tag;
225 	sc->sc_pc.pc_decompose_tag = octeon_pcibus_decompose_tag;
226 
227 	sc->sc_pc.pc_conf_v = sc;
228 	sc->sc_pc.pc_conf_size = octeon_pcibus_pci_conf_size;
229 	sc->sc_pc.pc_conf_read = octeon_pcibus_pci_conf_read;
230 	sc->sc_pc.pc_conf_write = octeon_pcibus_pci_conf_write;
231 
232 	sc->sc_pc.pc_intr_v = sc;
233 	sc->sc_pc.pc_intr_map = octeon_pcibus_pci_intr_map;
234 	sc->sc_pc.pc_intr_string = octeon_pcibus_pci_intr_string;
235 	sc->sc_pc.pc_intr_establish = octeon_pcibus_pci_intr_establish;
236 	sc->sc_pc.pc_intr_disestablish = octeon_pcibus_pci_intr_disestablish;
237 
238 	bzero(&pba, sizeof pba);
239 	pba.pba_busname = "pci";
240 	pba.pba_iot = &octeon_pcibus_pci_io_space_tag;
241 	pba.pba_memt = &octeon_pcibus_pci_mem_space_tag;
242 	pba.pba_dmat = &octeon_pcibus_bus_dma_tag;
243 	pba.pba_pc = &sc->sc_pc;
244 	pba.pba_domain = pci_ndomains++;
245 	pba.pba_bus = 0;
246 	pba.pba_ioex = octeon_pcibus_get_resource_extent(&sc->sc_pc, 1);
247 	pba.pba_memex = octeon_pcibus_get_resource_extent(&sc->sc_pc, 0);
248 
249 	config_found(&sc->sc_dev, &pba, octeon_pcibus_print);
250 }
251 
252 bus_addr_t
octeon_pcibus_pa_to_device(paddr_t pa)253 octeon_pcibus_pa_to_device(paddr_t pa)
254 {
255 	OCTEON_PCIDEBUG(("%s:%d: pa=%p\n", __func__, __LINE__, (void *)pa));
256 
257 	return pa & 0x1ffffffffffffUL;
258 }
259 
260 paddr_t
octeon_pcibus_device_to_pa(bus_addr_t addr)261 octeon_pcibus_device_to_pa(bus_addr_t addr)
262 {
263 	OCTEON_PCIDEBUG(("%s:%d: addr=%lx\n", __func__, __LINE__, addr));
264 
265 	return PHYS_TO_XKPHYS(addr, CCA_NC);
266 }
267 
268 int
octeon_pcibus_print(void * aux,const char * pnp)269 octeon_pcibus_print(void *aux, const char *pnp)
270 {
271 	struct pcibus_attach_args *pba = aux;
272 
273 	if (pnp)
274 		printf("%s at %s", pba->pba_busname, pnp);
275 	printf(" bus %d", pba->pba_bus);
276 
277 	return UNCONF;
278 }
279 
280 /*
281  * various PCI helpers
282  */
283 void
octeon_pcibus_attach_hook(struct device * parent,struct device * self,struct pcibus_attach_args * pba)284 octeon_pcibus_attach_hook(struct device *parent, struct device *self,
285     struct pcibus_attach_args *pba)
286 {
287 }
288 
289 /*
290  * PCI configuration space access routines
291  */
292 int
octeon_pcibus_bus_maxdevs(void * v,int busno)293 octeon_pcibus_bus_maxdevs(void *v, int busno)
294 {
295 	return (32);
296 }
297 
298 pcitag_t
octeon_pcibus_make_tag(void * unused,int b,int d,int f)299 octeon_pcibus_make_tag(void *unused, int b, int d, int f)
300 {
301 	return (b << 16) | (d << 11) | (f << 8);
302 }
303 
304 void
octeon_pcibus_decompose_tag(void * unused,pcitag_t tag,int * bp,int * dp,int * fp)305 octeon_pcibus_decompose_tag(void *unused, pcitag_t tag, int *bp, int *dp, int *fp)
306 {
307 	if (bp != NULL)
308 		*bp = (tag >> 16) & 0xff;
309 	if (dp != NULL)
310 		*dp = (tag >> 11) & 0x1f;
311 	if (fp != NULL)
312 		*fp = (tag >> 8) & 0x7;
313 }
314 
315 int
octeon_pcibus_pci_conf_size(void * v,pcitag_t tag)316 octeon_pcibus_pci_conf_size(void *v, pcitag_t tag)
317 {
318 	return PCI_CONFIG_SPACE_SIZE;
319 }
320 
321 pcireg_t
octeon_pcibus_pci_conf_read(void * v,pcitag_t tag,int offset)322 octeon_pcibus_pci_conf_read(void *v, pcitag_t tag, int offset)
323 {
324 	pcireg_t data;
325 	uint64_t cfgoff;
326 
327 	if (tag == 0){
328 		if (offset & 0x4){
329 			cfgoff = OCTEON_PCI_CFG1 + (offset & 0xfff8);
330 		} else {
331 			cfgoff = OCTEON_PCI_CFG0 + (offset & 0xfff8);
332 		}
333 	} else {
334 		cfgoff = tag + offset;
335 		if (offset & 0x4) {
336 			cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff & 0xfffffff8);
337 		} else {
338 			cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff & 0xfffffff8);
339 		}
340 	}
341 
342 	data = REG_READ32(cfgoff);
343 	return data;
344 }
345 
346 void
octeon_pcibus_pci_conf_write(void * v,pcitag_t tag,int offset,pcireg_t data)347 octeon_pcibus_pci_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
348 {
349 	uint64_t cfgoff;
350 
351 	if (tag == 0){
352 		if (offset & 0x4){
353 			cfgoff = OCTEON_PCI_CFG1 + (offset & 0xfff8);
354 		} else {
355 			cfgoff = OCTEON_PCI_CFG0 + (offset & 0xfff8);
356 		}
357 	} else {
358 		cfgoff = tag + offset;
359 		if (offset & 0x4){
360 			cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff & 0xfffffff8);
361 		} else {
362 			cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff & 0xfffffff8);
363 		}
364 	}
365 
366 	REG_WRITE32(cfgoff, data);
367 }
368 
369 
370 /*
371  * PCI Interrupt handling
372  */
373 int
octeon_pcibus_pci_intr_map(struct pci_attach_args * pa,pci_intr_handle_t * ihp)374 octeon_pcibus_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
375 {
376 #if 0
377 	struct octeon_pcibus_softc *sc = pa->pa_pc->pc_intr_v;
378 #endif
379 	int bus, dev, fn, pin;
380 
381 	*ihp = (pci_intr_handle_t)-1;
382 
383 	if (pa->pa_intrpin == 0)	/* no interrupt needed */
384 		return 1;
385 
386 #ifdef DIAGNOSTIC
387 	if (pa->pa_intrpin > 4) {
388 		printf("%s: bad interrupt pin %d\n", __func__, pa->pa_intrpin);
389 		return 1;
390 	}
391 #endif
392 
393 	pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &fn);
394 	if (pa->pa_bridgetag) {
395 		pin = PPB_INTERRUPT_SWIZZLE(pa->pa_rawintrpin, dev);
396 		*ihp = pa->pa_bridgeih[pin - 1];
397 	} else {
398 		if (bus == 0)
399 			*ihp = octeon_pcibus_intr_map(dev, fn, pa->pa_intrpin);
400 
401 		if (*ihp == (pci_intr_handle_t)-1)
402 			return 1;
403 	}
404 
405 	return 0;
406 }
407 
408 const char *
octeon_pcibus_pci_intr_string(void * cookie,pci_intr_handle_t ih)409 octeon_pcibus_pci_intr_string(void *cookie, pci_intr_handle_t ih)
410 {
411 	static char irqstr[sizeof("irq 0123456789")];
412 
413 	snprintf(irqstr, sizeof irqstr, "irq %ld", ih);
414 	return irqstr;
415 }
416 
417 void *
octeon_pcibus_pci_intr_establish(void * cookie,pci_intr_handle_t ih,int level,int (* cb)(void *),void * cbarg,char * name)418 octeon_pcibus_pci_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
419     int (*cb)(void *), void *cbarg, char *name)
420 {
421 	return octeon_intr_establish(ih, level, cb, cbarg, name);
422 }
423 
424 void
octeon_pcibus_pci_intr_disestablish(void * cookie,void * ihp)425 octeon_pcibus_pci_intr_disestablish(void *cookie, void *ihp)
426 {
427 	octeon_intr_disestablish(ihp);
428 }
429 
430 /*
431  * bus_space mapping routines.
432  */
433 int
octeon_pcibus_io_map(bus_space_tag_t t,bus_addr_t offs,bus_size_t size,int flags,bus_space_handle_t * bshp)434 octeon_pcibus_io_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
435     bus_space_handle_t *bshp)
436 {
437 	if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE)) {
438 		offs +=
439 		    PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC);
440 	}
441 	*bshp = t->bus_base + offs;
442 	return 0;
443 }
444 
445 int
octeon_pcibus_mem_map(bus_space_tag_t t,bus_addr_t offs,bus_size_t size,int flags,bus_space_handle_t * bshp)446 octeon_pcibus_mem_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
447     bus_space_handle_t *bshp)
448 {
449 	if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE)) {
450 		offs +=
451 		    PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC);
452 	}
453 	*bshp = t->bus_base + offs;
454 	return 0;
455 }
456 
457 /*
458  * PCI resource handling
459  */
460 struct extent *
octeon_pcibus_get_resource_extent(pci_chipset_tag_t pc,int io)461 octeon_pcibus_get_resource_extent(pci_chipset_tag_t pc, int io)
462 {
463 	struct octeon_pcibus_softc *sc = pc->pc_conf_v;
464 	struct extent *ex;
465 	char *exname;
466 	int exnamesz;
467 
468 	exnamesz = 1 + 16 + 4;
469 	exname = malloc(exnamesz, M_DEVBUF, M_NOWAIT);
470 	if (exname == NULL)
471 		return NULL;
472 	snprintf(exname, exnamesz, "%s%s", sc->sc_dev.dv_xname,
473 	    io ? "_io" : "_mem");
474 
475 	ex = extent_create(exname, 0, 0xffffffffffffffff, M_DEVBUF, NULL, 0,
476 	    EX_NOWAIT | EX_FILLED);
477 	if (ex == NULL)
478 		goto error;
479 
480 	if (io) {
481 		if (extent_free(ex, _OCTEON_PCIBUS_PCIIO_BASE,
482 		    _OCTEON_PCIBUS_PCIIO_SIZE, EX_NOWAIT) != 0)
483 			goto error;
484 	} else {
485 		if (extent_free(ex, _OCTEON_PCIBUS_PCIMEM_BASE,
486 		    _OCTEON_PCIBUS_PCIMEM_SIZE, EX_NOWAIT) != 0)
487 			goto error;
488 	}
489 
490 #if defined(DEBUG) && defined(DIAGNOSTIC)
491 	extent_print(ex);
492 #endif
493 	return ex;
494 
495 error:
496 	if (ex != NULL)
497 		extent_destroy(ex);
498 	free(exname, M_DEVBUF, exnamesz);
499 	return NULL;
500 }
501 
502 /*
503  * PCI model specific routines
504  */
505 
506 int
octeon_pcibus_intr_map(int dev,int fn,int pin)507 octeon_pcibus_intr_map(int dev, int fn, int pin)
508 {
509 	return CIU_INT_PCI_INTA + ((pin - 1) & 3);
510 }
511