Skip to content

Commit

Permalink
kvmtool: ARM: allow level interrupts in device tree
Browse files Browse the repository at this point in the history
Currently we describe every interrupt for each device in the FDT
as being edge triggered.
Add a parameter to the irq property generation to allow devices to
specify their interrupts as level triggered if needed.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
  • Loading branch information
Andre-ARM authored and wildea01 committed Dec 17, 2014
1 parent d309475 commit 6f0b485
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 15 deletions.
6 changes: 3 additions & 3 deletions tools/kvm/arm/fdt.c
Expand Up @@ -74,12 +74,12 @@ static void generate_cpu_nodes(void *fdt, struct kvm *kvm)
_FDT(fdt_end_node(fdt));
}

static void generate_irq_prop(void *fdt, u8 irq)
static void generate_irq_prop(void *fdt, u8 irq, enum irq_type irq_type)
{
u32 irq_prop[] = {
cpu_to_fdt32(GIC_FDT_IRQ_TYPE_SPI),
cpu_to_fdt32(irq - GIC_SPI_IRQ_BASE),
cpu_to_fdt32(IRQ_TYPE_EDGE_RISING),
cpu_to_fdt32(irq_type)
};

_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
Expand Down Expand Up @@ -127,7 +127,7 @@ static int setup_fdt(struct kvm *kvm)
void *fdt_dest = guest_flat_to_host(kvm,
kvm->arch.dtb_guest_start);
void (*generate_mmio_fdt_nodes)(void *, struct device_header *,
void (*)(void *, u8));
void (*)(void *, u8, enum irq_type));
void (*generate_cpu_peripheral_fdt_nodes)(void *, struct kvm *, u32)
= kvm->cpus[0]->generate_fdt_nodes;

Expand Down
10 changes: 6 additions & 4 deletions tools/kvm/hw/serial.c
Expand Up @@ -367,9 +367,11 @@ static bool serial8250_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port,

#ifdef CONFIG_HAS_LIBFDT
#define DEVICE_NAME_MAX_LEN 32
static void serial8250_generate_fdt_node(struct ioport *ioport, void *fdt,
void (*generate_irq_prop)(void *fdt,
u8 irq))
static
void serial8250_generate_fdt_node(struct ioport *ioport, void *fdt,
void (*generate_irq_prop)(void *fdt,
u8 irq,
enum irq_type))
{
char dev_name[DEVICE_NAME_MAX_LEN];
struct serial8250_device *dev = ioport->priv;
Expand All @@ -384,7 +386,7 @@ static void serial8250_generate_fdt_node(struct ioport *ioport, void *fdt,
_FDT(fdt_begin_node(fdt, dev_name));
_FDT(fdt_property_string(fdt, "compatible", "ns16550a"));
_FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop)));
generate_irq_prop(fdt, dev->irq);
generate_irq_prop(fdt, dev->irq, IRQ_TYPE_EDGE_RISING);
_FDT(fdt_property_cell(fdt, "clock-frequency", 1843200));
_FDT(fdt_end_node(fdt));
}
Expand Down
5 changes: 4 additions & 1 deletion tools/kvm/include/kvm/ioport.h
Expand Up @@ -4,6 +4,7 @@
#include "kvm/devices.h"
#include "kvm/kvm-cpu.h"
#include "kvm/rbtree-interval.h"
#include "kvm/fdt.h"

#include <stdbool.h>
#include <limits.h>
Expand Down Expand Up @@ -31,7 +32,9 @@ struct ioport_operations {
bool (*io_in)(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size);
bool (*io_out)(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size);
void (*generate_fdt_node)(struct ioport *ioport, void *fdt,
void (*generate_irq_prop)(void *fdt, u8 irq));
void (*generate_irq_prop)(void *fdt,
u8 irq,
enum irq_type));
};

void ioport__setup_arch(struct kvm *kvm);
Expand Down
6 changes: 4 additions & 2 deletions tools/kvm/ioport.c
Expand Up @@ -59,7 +59,8 @@ static void ioport_remove(struct rb_root *root, struct ioport *data)
static void generate_ioport_fdt_node(void *fdt,
struct device_header *dev_hdr,
void (*generate_irq_prop)(void *fdt,
u8 irq))
u8 irq,
enum irq_type))
{
struct ioport *ioport = container_of(dev_hdr, struct ioport, dev_hdr);
struct ioport_operations *ops = ioport->ops;
Expand All @@ -71,7 +72,8 @@ static void generate_ioport_fdt_node(void *fdt,
static void generate_ioport_fdt_node(void *fdt,
struct device_header *dev_hdr,
void (*generate_irq_prop)(void *fdt,
u8 irq))
u8 irq,
enum irq_type))
{
die("Unable to generate device tree nodes without libfdt\n");
}
Expand Down
12 changes: 7 additions & 5 deletions tools/kvm/virtio/mmio.c
Expand Up @@ -230,10 +230,12 @@ static void virtio_mmio_mmio_callback(struct kvm_cpu *vcpu,

#ifdef CONFIG_HAS_LIBFDT
#define DEVICE_NAME_MAX_LEN 32
static void generate_virtio_mmio_fdt_node(void *fdt,
struct device_header *dev_hdr,
void (*generate_irq_prop)(void *fdt,
u8 irq))
static
void generate_virtio_mmio_fdt_node(void *fdt,
struct device_header *dev_hdr,
void (*generate_irq_prop)(void *fdt,
u8 irq,
enum irq_type))
{
char dev_name[DEVICE_NAME_MAX_LEN];
struct virtio_mmio *vmmio = container_of(dev_hdr,
Expand All @@ -250,7 +252,7 @@ static void generate_virtio_mmio_fdt_node(void *fdt,
_FDT(fdt_begin_node(fdt, dev_name));
_FDT(fdt_property_string(fdt, "compatible", "virtio,mmio"));
_FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop)));
generate_irq_prop(fdt, vmmio->irq);
generate_irq_prop(fdt, vmmio->irq, IRQ_TYPE_EDGE_RISING);
_FDT(fdt_end_node(fdt));
}
#else
Expand Down

0 comments on commit 6f0b485

Please sign in to comment.