Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tegra v2 #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions xen/arch/arm/Rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ EARLY_PRINTK_vexpress := pl011,0x1c090000
EARLY_PRINTK_xgene-mcdivitt := 8250,0x1c021000,2
EARLY_PRINTK_xgene-storm := 8250,0x1c020000,2
EARLY_PRINTK_zynqmp := cadence,0xff000000
EARLY_PRINTK_tegra := 8250,0x70006000,2

ifneq ($(EARLY_PRINTK_$(CONFIG_EARLY_PRINTK)),)
EARLY_PRINTK_CFG := $(subst $(comma), ,$(EARLY_PRINTK_$(CONFIG_EARLY_PRINTK)))
Expand Down
29 changes: 23 additions & 6 deletions xen/arch/arm/domain_build.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,8 @@ static int make_gic_node(const struct domain *d, void *fdt,
{
const struct dt_device_node *gic = dt_interrupt_controller;
int res = 0;
const void *addrcells, *sizecells;
u32 addrcells_len, sizecells_len;
const void *addrcells, *sizecells, *iparent;
u32 addrcells_len, sizecells_len, iparent_len;

/*
* Xen currently supports only a single GIC. Discard any secondary
Expand Down Expand Up @@ -809,6 +809,19 @@ static int make_gic_node(const struct domain *d, void *fdt,
return res;
}

/*
* If available, explicitly inherit interrupt-parent property from host
* device tree. This will prevent the risk of incorrect identification
* of the parent on platforms with more than one interrupt controller.
*/
iparent = dt_get_property(gic, "interrupt-parent", &iparent_len);
if ( iparent )
{
res = fdt_property(fdt, "interrupt-parent", iparent, iparent_len);
if ( res )
return res;
}

addrcells = dt_get_property(gic, "#address-cells", &addrcells_len);
if ( addrcells )
{
Expand Down Expand Up @@ -1107,12 +1120,16 @@ static int handle_device(struct domain *d, struct dt_device_node *dev,

/*
* Don't map IRQ that have no physical meaning
* ie: IRQ whose controller is not the GIC
* ie: IRQ that does not wind up being controlled by the GIC
* (Note that we can't just check to see if an IRQ is owned by the GIC,
* as some platforms have a controller between the device irq and the GIC,
* such as the Tegra legacy interrupt controller.)
*/
if ( rirq.controller != dt_interrupt_controller )
if ( !platform_irq_is_routable(&rirq) )
{
dt_dprintk("irq %u not connected to primary controller. Connected to %s\n",
i, dt_node_full_name(rirq.controller));
dt_dprintk("irq %u not (directly or indirectly) connected to primary"
"controller. Connected to %s\n", i,
dt_node_full_name(rirq.controller));
continue;
}

Expand Down
15 changes: 13 additions & 2 deletions xen/arch/arm/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <asm/gic.h>
#include <asm/vgic.h>
#include <asm/platform.h>

static unsigned int local_irqs_type[NR_LOCAL_IRQS];
static DEFINE_SPINLOCK(local_irqs_type_lock);
Expand Down Expand Up @@ -142,6 +143,16 @@ static inline struct domain *irq_get_domain(struct irq_desc *desc)
return irq_get_guest_info(desc)->d;
}

domid_t irq_get_domain_id(struct irq_desc *desc)
{
/* If this domain isn't routed to a guest, return DOMID_XEN. */
if ( !test_bit(_IRQ_GUEST, &desc->status) )
return DOMID_XEN;

/* Otherise, get the guest domain's information. */
return irq_get_domain(desc)->domain_id;
}

void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask)
{
if ( desc != NULL )
Expand Down Expand Up @@ -369,7 +380,7 @@ int setup_irq(unsigned int irq, unsigned int irqflags, struct irqaction *new)
/* First time the IRQ is setup */
if ( disabled )
{
gic_route_irq_to_xen(desc, GIC_PRI_IRQ);
platform_route_irq_to_xen(desc, GIC_PRI_IRQ);
/* It's fine to use smp_processor_id() because:
* For PPI: irq_desc is banked
* For SPI: we don't care for now which CPU will receive the
Expand Down Expand Up @@ -506,7 +517,7 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
if ( retval )
goto out;

retval = gic_route_irq_to_guest(d, virq, desc, GIC_PRI_IRQ);
retval = platform_route_irq_to_guest(d, virq, desc, GIC_PRI_IRQ);

spin_unlock_irqrestore(&desc->lock, flags);

Expand Down
30 changes: 30 additions & 0 deletions xen/arch/arm/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,36 @@ bool_t platform_device_is_blacklisted(const struct dt_device_node *node)
return (dt_match_node(blacklist, node) != NULL);
}

int platform_route_irq_to_guest(struct domain *d, unsigned int virq,
struct irq_desc *desc, unsigned int priority)
{
if ( platform && platform->route_irq_to_guest )
return platform->route_irq_to_guest(d, virq, desc, priority);
else
return gic_route_irq_to_guest(d, virq, desc, priority);
}

void platform_route_irq_to_xen(struct irq_desc *desc, unsigned int priority)
{
if ( platform && platform->route_irq_to_xen )
platform->route_irq_to_xen(desc, priority);
else
gic_route_irq_to_xen(desc, priority);
}

bool platform_irq_is_routable(const struct dt_raw_irq * rirq)
{
/*
* If we have a platform-specific method to determine if an IRQ is routable,
* check that; otherwise fall back to checking to see if an IRQ belongs to
* the GIC.
*/
if ( platform && platform->irq_is_routable )
return platform->irq_is_routable(rirq);
else
return (rirq->controller == dt_interrupt_controller);
}

/*
* Local variables:
* mode: C
Expand Down
4 changes: 4 additions & 0 deletions xen/arch/arm/platforms/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@ obj-$(CONFIG_ARM_32) += omap5.o
obj-$(CONFIG_ARM_32) += rcar2.o
obj-$(CONFIG_ARM_64) += seattle.o
obj-$(CONFIG_ARM_32) += sunxi.o
obj-$(CONFIG_ARM_32) += tegra.o
obj-$(CONFIG_ARM_32) += tegra-mlic.o
obj-$(CONFIG_ARM_64) += tegra.o
obj-$(CONFIG_ARM_64) += tegra-mlic.o
obj-$(CONFIG_ARM_64) += xgene-storm.o
obj-$(CONFIG_ARM_64) += xilinx-zynqmp.o
Loading