2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 2013 Cavium, Inc.
9 #include <linux/kernel.h>
10 #include <linux/init.h>
11 #include <linux/interrupt.h>
12 #include <linux/pci.h>
14 #include <uapi/asm/bitfield.h>
15 #include <asm/byteorder.h>
18 #define PCI_CONFIG_ADDRESS 0xcf8
19 #define PCI_CONFIG_DATA 0xcfc
21 union pci_config_address
{
23 __BITFIELD_FIELD(unsigned enable_bit
: 1, /* 31 */
24 __BITFIELD_FIELD(unsigned reserved
: 7, /* 30 .. 24 */
25 __BITFIELD_FIELD(unsigned bus_number
: 8, /* 23 .. 16 */
26 __BITFIELD_FIELD(unsigned devfn_number
: 8, /* 15 .. 8 */
27 __BITFIELD_FIELD(unsigned register_number
: 8, /* 7 .. 0 */
33 int pcibios_plat_dev_init(struct pci_dev
*dev
)
38 int pcibios_map_irq(const struct pci_dev
*dev
, u8 slot
, u8 pin
)
40 return ((pin
+ slot
) % 4)+ MIPS_IRQ_PCIA
;
43 static void pci_virtio_guest_write_config_addr(struct pci_bus
*bus
,
44 unsigned int devfn
, int reg
)
46 union pci_config_address pca
= { .w
= 0 };
48 pca
.register_number
= reg
;
49 pca
.devfn_number
= devfn
;
50 pca
.bus_number
= bus
->number
;
53 outl(pca
.w
, PCI_CONFIG_ADDRESS
);
56 static int pci_virtio_guest_write_config(struct pci_bus
*bus
,
57 unsigned int devfn
, int reg
, int size
, u32 val
)
59 pci_virtio_guest_write_config_addr(bus
, devfn
, reg
);
63 outb(val
, PCI_CONFIG_DATA
+ (reg
& 3));
66 outw(val
, PCI_CONFIG_DATA
+ (reg
& 2));
69 outl(val
, PCI_CONFIG_DATA
);
73 return PCIBIOS_SUCCESSFUL
;
76 static int pci_virtio_guest_read_config(struct pci_bus
*bus
, unsigned int devfn
,
77 int reg
, int size
, u32
*val
)
79 pci_virtio_guest_write_config_addr(bus
, devfn
, reg
);
83 *val
= inb(PCI_CONFIG_DATA
+ (reg
& 3));
86 *val
= inw(PCI_CONFIG_DATA
+ (reg
& 2));
89 *val
= inl(PCI_CONFIG_DATA
);
92 return PCIBIOS_SUCCESSFUL
;
95 static struct pci_ops pci_virtio_guest_ops
= {
96 .read
= pci_virtio_guest_read_config
,
97 .write
= pci_virtio_guest_write_config
,
100 static struct resource pci_virtio_guest_mem_resource
= {
101 .name
= "Virtio MEM",
102 .flags
= IORESOURCE_MEM
,
107 static struct resource pci_virtio_guest_io_resource
= {
109 .flags
= IORESOURCE_IO
,
114 static struct pci_controller pci_virtio_guest_controller
= {
115 .pci_ops
= &pci_virtio_guest_ops
,
116 .mem_resource
= &pci_virtio_guest_mem_resource
,
117 .io_resource
= &pci_virtio_guest_io_resource
,
120 static int __init
pci_virtio_guest_setup(void)
122 pr_err("pci_virtio_guest_setup\n");
124 /* Virtio comes pre-assigned */
125 pci_set_flags(PCI_PROBE_ONLY
);
127 pci_virtio_guest_controller
.io_map_base
= mips_io_port_base
;
128 register_pci_controller(&pci_virtio_guest_controller
);
131 arch_initcall(pci_virtio_guest_setup
);