Not to be applied until better understood.

Linux has these hooks and uses them on Tegra.

However I don't think they are strictly needed (only for power gating stuff
perhaps?). I implemented them while investigating some other issues, used by
later "Tegra hacking" patch which isn't actually needed for a working board,
AFAICT.

Signed-off-by: Ian Campbell <ian.campb...@citrix.com>
---
 xen/arch/arm/gic-v2.c          |  3 +++
 xen/arch/arm/platform.c        | 16 ++++++++++++++++
 xen/include/asm-arm/platform.h |  8 ++++++++
 3 files changed, 27 insertions(+)

diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 2f5d33b..033a94a 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -537,6 +537,7 @@ static void gicv2_irq_enable(struct irq_desc *desc)
     clear_bit(_IRQ_DISABLED, &desc->status);
     dsb(sy);
     /* Enable routing */
+    platform_irq_unmask(desc);
     writel_gicd((1u << (irq % 32)), GICD_ISENABLER + (irq / 32) * 4);
     spin_unlock_irqrestore(&gicv2.lock, flags);
 }
@@ -552,6 +553,7 @@ static void gicv2_irq_disable(struct irq_desc *desc)
     /* Disable routing */
     writel_gicd(1u << (irq % 32), GICD_ICENABLER + (irq / 32) * 4);
     set_bit(_IRQ_DISABLED, &desc->status);
+    platform_irq_mask(desc);
     spin_unlock_irqrestore(&gicv2.lock, flags);
 }
 
@@ -574,6 +576,7 @@ static void gicv2_irq_ack(struct irq_desc *desc)
 
 static void gicv2_host_irq_end(struct irq_desc *desc)
 {
+    platform_irq_eoi(desc);
     /* Lower the priority */
     gicv2_eoi_irq(desc);
     /* Deactivate */
diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
index c58e251..3255c6a 100644
--- a/xen/arch/arm/platform.c
+++ b/xen/arch/arm/platform.c
@@ -160,6 +160,22 @@ bool_t platform_device_is_blacklisted(const struct 
dt_device_node *node)
     return (dt_match_node(blacklist, node) != NULL);
 }
 
+void platform_irq_eoi(struct irq_desc *desc)
+{
+    if ( platform && platform->irq_eoi )
+        platform->irq_eoi(desc);
+}
+void platform_irq_mask(struct irq_desc *desc)
+{
+    if ( platform && platform->irq_mask )
+        platform->irq_mask(desc);
+}
+void platform_irq_unmask(struct irq_desc *desc)
+{
+    if ( platform && platform->irq_unmask )
+        platform->irq_unmask(desc);
+}
+
 void platform_route_irq_to_guest(struct domain *d, struct irq_desc *desc)
 {
     if ( platform && platform->route_irq_to_guest )
diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
index 22d1f8b..8b4c807 100644
--- a/xen/include/asm-arm/platform.h
+++ b/xen/include/asm-arm/platform.h
@@ -27,6 +27,11 @@ struct platform_desc {
     /* Platform power-off */
     void (*poweroff)(void);
 
+    /* GIC hooks */
+    void (*irq_eoi)(struct irq_desc *);
+    void (*irq_mask)(struct irq_desc *);
+    void (*irq_unmask)(struct irq_desc *);
+
     void (*route_irq_to_guest)(struct domain *d, struct irq_desc *);
 
     /*
@@ -72,6 +77,9 @@ bool_t platform_has_quirk(uint32_t quirk);
 bool_t platform_device_is_blacklisted(const struct dt_device_node *node);
 unsigned int platform_dom0_evtchn_ppi(void);
 void platform_dom0_gnttab(paddr_t *start, paddr_t *size);
+void platform_irq_eoi(struct irq_desc *);
+void platform_irq_mask(struct irq_desc *);
+void platform_irq_unmask(struct irq_desc *);
 
 void platform_route_irq_to_guest(struct domain *, struct irq_desc *);
 
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

Reply via email to