aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorDavid Daney <david.daney@cavium.com>2014-05-28 17:52:14 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-06-02 06:34:20 -0400
commitae6e7e635c2c9aa5aa5c03f5ac39e9d84fc0ee09 (patch)
tree76c1c92639f115fa1427a12644ca14e1c5ea24fd /arch/mips
parent18280edafef1b8ffc920743eddaf6cf6612b1509 (diff)
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>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Kconfig1
-rw-r--r--arch/mips/paravirt/Kconfig6
-rw-r--r--arch/mips/pci/Makefile2
-rw-r--r--arch/mips/pci/pci-virtio-guest.c131
4 files changed, 139 insertions, 1 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 78b558f77f5c..e41f32b890fc 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -825,6 +825,7 @@ source "arch/mips/cavium-octeon/Kconfig"
825source "arch/mips/loongson/Kconfig" 825source "arch/mips/loongson/Kconfig"
826source "arch/mips/loongson1/Kconfig" 826source "arch/mips/loongson1/Kconfig"
827source "arch/mips/netlogic/Kconfig" 827source "arch/mips/netlogic/Kconfig"
828source "arch/mips/paravirt/Kconfig"
828 829
829endmenu 830endmenu
830 831
diff --git a/arch/mips/paravirt/Kconfig b/arch/mips/paravirt/Kconfig
new file mode 100644
index 000000000000..ecae5861b601
--- /dev/null
+++ b/arch/mips/paravirt/Kconfig
@@ -0,0 +1,6 @@
1if MIPS_PARAVIRT
2
3config MIPS_PCI_VIRTIO
4 def_bool y
5
6endif # MIPS_PARAVIRT
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index d61138a177cc..ff8a5539b363 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -21,7 +21,7 @@ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
21obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o 21obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
22obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o 22obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
23obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o 23obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
24 24obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
25# 25#
26# These are still pretty much in the old state, watch, go blind. 26# These are still pretty much in the old state, watch, go blind.
27# 27#
diff --git a/arch/mips/pci/pci-virtio-guest.c b/arch/mips/pci/pci-virtio-guest.c
new file mode 100644
index 000000000000..40a078bc4617
--- /dev/null
+++ b/arch/mips/pci/pci-virtio-guest.c
@@ -0,0 +1,131 @@
1/*
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
4 * for more details.
5 *
6 * Copyright (C) 2013 Cavium, Inc.
7 */
8
9#include <linux/kernel.h>
10#include <linux/init.h>
11#include <linux/interrupt.h>
12#include <linux/pci.h>
13
14#include <uapi/asm/bitfield.h>
15#include <asm/byteorder.h>
16#include <asm/io.h>
17
18#define PCI_CONFIG_ADDRESS 0xcf8
19#define PCI_CONFIG_DATA 0xcfc
20
21union pci_config_address {
22 struct {
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 */
28 )))));
29 };
30 u32 w;
31};
32
33int pcibios_plat_dev_init(struct pci_dev *dev)
34{
35 return 0;
36}
37
38int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
39{
40 return ((pin + slot) % 4)+ MIPS_IRQ_PCIA;
41}
42
43static void pci_virtio_guest_write_config_addr(struct pci_bus *bus,
44 unsigned int devfn, int reg)
45{
46 union pci_config_address pca = { .w = 0 };
47
48 pca.register_number = reg;
49 pca.devfn_number = devfn;
50 pca.bus_number = bus->number;
51 pca.enable_bit = 1;
52
53 outl(pca.w, PCI_CONFIG_ADDRESS);
54}
55
56static int pci_virtio_guest_write_config(struct pci_bus *bus,
57 unsigned int devfn, int reg, int size, u32 val)
58{
59 pci_virtio_guest_write_config_addr(bus, devfn, reg);
60
61 switch (size) {
62 case 1:
63 outb(val, PCI_CONFIG_DATA + (reg & 3));
64 break;
65 case 2:
66 outw(val, PCI_CONFIG_DATA + (reg & 2));
67 break;
68 case 4:
69 outl(val, PCI_CONFIG_DATA);
70 break;
71 }
72
73 return PCIBIOS_SUCCESSFUL;
74}
75
76static int pci_virtio_guest_read_config(struct pci_bus *bus, unsigned int devfn,
77 int reg, int size, u32 *val)
78{
79 pci_virtio_guest_write_config_addr(bus, devfn, reg);
80
81 switch (size) {
82 case 1:
83 *val = inb(PCI_CONFIG_DATA + (reg & 3));
84 break;
85 case 2:
86 *val = inw(PCI_CONFIG_DATA + (reg & 2));
87 break;
88 case 4:
89 *val = inl(PCI_CONFIG_DATA);
90 break;
91 }
92 return PCIBIOS_SUCCESSFUL;
93}
94
95static struct pci_ops pci_virtio_guest_ops = {
96 .read = pci_virtio_guest_read_config,
97 .write = pci_virtio_guest_write_config,
98};
99
100static struct resource pci_virtio_guest_mem_resource = {
101 .name = "Virtio MEM",
102 .flags = IORESOURCE_MEM,
103 .start = 0x10000000,
104 .end = 0x1dffffff
105};
106
107static struct resource pci_virtio_guest_io_resource = {
108 .name = "Virtio IO",
109 .flags = IORESOURCE_IO,
110 .start = 0,
111 .end = 0xffff
112};
113
114static 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,
118};
119
120static int __init pci_virtio_guest_setup(void)
121{
122 pr_err("pci_virtio_guest_setup\n");
123
124 /* Virtio comes pre-assigned */
125 pci_set_flags(PCI_PROBE_ONLY);
126
127 pci_virtio_guest_controller.io_map_base = mips_io_port_base;
128 register_pci_controller(&pci_virtio_guest_controller);
129 return 0;
130}
131arch_initcall(pci_virtio_guest_setup);