123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2013 Cavium, Inc.
- */
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/pci.h>
- #include <uapi/asm/bitfield.h>
- #include <asm/byteorder.h>
- #include <asm/io.h>
- #define PCI_CONFIG_ADDRESS 0xcf8
- #define PCI_CONFIG_DATA 0xcfc
- union pci_config_address {
- struct {
- __BITFIELD_FIELD(unsigned enable_bit : 1, /* 31 */
- __BITFIELD_FIELD(unsigned reserved : 7, /* 30 .. 24 */
- __BITFIELD_FIELD(unsigned bus_number : 8, /* 23 .. 16 */
- __BITFIELD_FIELD(unsigned devfn_number : 8, /* 15 .. 8 */
- __BITFIELD_FIELD(unsigned register_number : 8, /* 7 .. 0 */
- )))));
- };
- u32 w;
- };
- int pcibios_plat_dev_init(struct pci_dev *dev)
- {
- return 0;
- }
- int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
- {
- return ((pin + slot) % 4)+ MIPS_IRQ_PCIA;
- }
- static void pci_virtio_guest_write_config_addr(struct pci_bus *bus,
- unsigned int devfn, int reg)
- {
- union pci_config_address pca = { .w = 0 };
- pca.register_number = reg;
- pca.devfn_number = devfn;
- pca.bus_number = bus->number;
- pca.enable_bit = 1;
- outl(pca.w, PCI_CONFIG_ADDRESS);
- }
- static int pci_virtio_guest_write_config(struct pci_bus *bus,
- unsigned int devfn, int reg, int size, u32 val)
- {
- pci_virtio_guest_write_config_addr(bus, devfn, reg);
- switch (size) {
- case 1:
- outb(val, PCI_CONFIG_DATA + (reg & 3));
- break;
- case 2:
- outw(val, PCI_CONFIG_DATA + (reg & 2));
- break;
- case 4:
- outl(val, PCI_CONFIG_DATA);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
- }
- static int pci_virtio_guest_read_config(struct pci_bus *bus, unsigned int devfn,
- int reg, int size, u32 *val)
- {
- pci_virtio_guest_write_config_addr(bus, devfn, reg);
- switch (size) {
- case 1:
- *val = inb(PCI_CONFIG_DATA + (reg & 3));
- break;
- case 2:
- *val = inw(PCI_CONFIG_DATA + (reg & 2));
- break;
- case 4:
- *val = inl(PCI_CONFIG_DATA);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
- }
- static struct pci_ops pci_virtio_guest_ops = {
- .read = pci_virtio_guest_read_config,
- .write = pci_virtio_guest_write_config,
- };
- static struct resource pci_virtio_guest_mem_resource = {
- .name = "Virtio MEM",
- .flags = IORESOURCE_MEM,
- .start = 0x10000000,
- .end = 0x1dffffff
- };
- static struct resource pci_virtio_guest_io_resource = {
- .name = "Virtio IO",
- .flags = IORESOURCE_IO,
- .start = 0,
- .end = 0xffff
- };
- static struct pci_controller pci_virtio_guest_controller = {
- .pci_ops = &pci_virtio_guest_ops,
- .mem_resource = &pci_virtio_guest_mem_resource,
- .io_resource = &pci_virtio_guest_io_resource,
- };
- static int __init pci_virtio_guest_setup(void)
- {
- pr_err("pci_virtio_guest_setup\n");
- /* Virtio comes pre-assigned */
- pci_set_flags(PCI_PROBE_ONLY);
- pci_virtio_guest_controller.io_map_base = mips_io_port_base;
- register_pci_controller(&pci_virtio_guest_controller);
- return 0;
- }
- arch_initcall(pci_virtio_guest_setup);
|