mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 07:00:48 +00:00
MIPS: paravirt: Add pci controller for virtio
Signed-off-by: David Daney <david.daney@cavium.com> Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com> Cc: linux-mips@linux-mips.org Cc: James Hogan <james.hogan@imgtec.com> Cc: kvm@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7011/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
18280edafe
commit
ae6e7e635c
@ -825,6 +825,7 @@ source "arch/mips/cavium-octeon/Kconfig"
|
||||
source "arch/mips/loongson/Kconfig"
|
||||
source "arch/mips/loongson1/Kconfig"
|
||||
source "arch/mips/netlogic/Kconfig"
|
||||
source "arch/mips/paravirt/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
|
6
arch/mips/paravirt/Kconfig
Normal file
6
arch/mips/paravirt/Kconfig
Normal file
@ -0,0 +1,6 @@
|
||||
if MIPS_PARAVIRT
|
||||
|
||||
config MIPS_PCI_VIRTIO
|
||||
def_bool y
|
||||
|
||||
endif # MIPS_PARAVIRT
|
@ -21,7 +21,7 @@ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
|
||||
obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
|
||||
obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
|
||||
obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
|
||||
|
||||
obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
|
||||
#
|
||||
# These are still pretty much in the old state, watch, go blind.
|
||||
#
|
||||
|
131
arch/mips/pci/pci-virtio-guest.c
Normal file
131
arch/mips/pci/pci-virtio-guest.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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);
|
Loading…
x
Reference in New Issue
Block a user