From mboxrd@z Thu Jan 1 00:00:00 1970 From: Subject: [PATCH v8 10/28] xen/arm: ITS: Implement hw_irq_controller for LPIs Date: Mon, 1 Feb 2016 14:56:20 +0530 Message-ID: <1454318798-31913-11-git-send-email-vijayak@caviumnetworks.com> References: <1454318798-31913-1-git-send-email-vijayak@caviumnetworks.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1454318798-31913-1-git-send-email-vijayak@caviumnetworks.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Ian.Campbell@citrix.com, julien.grall@citrix.com, stefano.stabellini@eu.citrix.com, stefano.stabellini@citrix.com, tim@xen.org, xen-devel@lists.xen.org Cc: Prasun.Kapoor@caviumnetworks.com, manish.jaggi@caviumnetworks.com, Vijaya Kumar K , vijay.kilari@gmail.com List-Id: xen-devel@lists.xenproject.org From: Vijaya Kumar K Implement hw_irq_controller callbacks required to handle LPIs. Signed-off-by: Vijaya Kumar K Reviewed-by: Julien Grall --- v8: - Removed const before hw_irq_controller for lpis v7: - Split this patch into two. In this patch implement only hw_irq_controller callbacks for LPIs. v6: - Moved this patch #15 in v5 to patch #9 - Introduce inv command - Moved msi_desc helper functions to separate "xen/arm: ITS: Introduce msi_desc for LPIs" - Exported LPI hw_irq_controller structure and removed helper function to access. v5: - Fixed review comments - Exposed gicv3_[host|guest]_irq_end and hook to its v4: - Implement separate hw_irq_controller for LPIs - Drop setting LPI affinity - virq and vid are moved under union - Introduced inv command handling - its_device is stored in irq_desc --- xen/arch/arm/gic-v3-its.c | 119 +++++++++++++++++++++++++++++++++++++ xen/arch/arm/gic-v3.c | 2 +- xen/include/asm-arm/gic_v3_defs.h | 2 + 3 files changed, 122 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c index c233950..fa88a75 100644 --- a/xen/arch/arm/gic-v3-its.c +++ b/xen/arch/arm/gic-v3-its.c @@ -446,6 +446,125 @@ static void its_send_discard(struct its_device *dev, u32 event) its_send_single_command(dev->its, &cmd, col); } +static void its_flush_and_invalidate_prop(struct irq_desc *desc, const u8 *cfg) +{ + struct its_device *its_dev = irqdesc_get_its_device(desc); + u32 vid = irqdesc_get_lpi_event(desc); + + ASSERT(vid < its_dev->event_map.nr_lpis); + + /* + * Make the above write visible to the redistributors. + * And yes, we're flushing exactly: One. Single. Byte. + * Humpf... + */ + if ( gic_rdists->flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING ) + clean_and_invalidate_dcache_va_range(cfg, sizeof(*cfg)); + else + dsb(ishst); + + its_send_inv(its_dev, vid); +} + +static void its_set_lpi_state(struct irq_desc *desc, int enable) +{ + u8 *cfg; + + ASSERT(spin_is_locked(&its_lock)); + + cfg = gic_rdists->prop_page + desc->irq - FIRST_GIC_LPI; + if ( enable ) + *cfg |= LPI_PROP_ENABLED; + else + *cfg &= ~LPI_PROP_ENABLED; + + its_flush_and_invalidate_prop(desc, cfg); +} + +static void its_irq_enable(struct irq_desc *desc) +{ + unsigned long flags; + + ASSERT(spin_is_locked(&desc->lock)); + + spin_lock_irqsave(&its_lock, flags); + clear_bit(_IRQ_DISABLED, &desc->status); + dsb(sy); + its_set_lpi_state(desc, 1); + spin_unlock_irqrestore(&its_lock, flags); +} + +static void its_irq_disable(struct irq_desc *desc) +{ + unsigned long flags; + + ASSERT(spin_is_locked(&desc->lock)); + + spin_lock_irqsave(&its_lock, flags); + its_set_lpi_state(desc, 0); + set_bit(_IRQ_DISABLED, &desc->status); + spin_unlock_irqrestore(&its_lock, flags); +} + +static unsigned int its_irq_startup(struct irq_desc *desc) +{ + its_irq_enable(desc); + + return 0; +} + +static void its_irq_shutdown(struct irq_desc *desc) +{ + its_irq_disable(desc); +} + +static void its_irq_ack(struct irq_desc *desc) +{ + /* No ACK -- reading IAR has done this for us */ +} + +static void its_host_irq_end(struct irq_desc *desc) +{ + /* Lower the priority */ + gicv3_eoi_irq(desc); + /* LPIs does not have active state. Do not deactivate */ +} + +static void its_guest_irq_end(struct irq_desc *desc) +{ + gicv3_eoi_irq(desc); +} + +static void its_irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask) +{ + /*TODO: Yet to support */ + printk(XENLOG_G_WARNING "ITS: Setting Affinity of LPI is not supported\n"); + + return; +} + +hw_irq_controller its_host_lpi_type = { + .typename = "gic-its", + .startup = its_irq_startup, + .shutdown = its_irq_shutdown, + .enable = its_irq_enable, + .disable = its_irq_disable, + .ack = its_irq_ack, + .end = its_host_irq_end, + .set_affinity = its_irq_set_affinity, +}; + +hw_irq_controller its_guest_lpi_type = { + .typename = "gic-its", + .startup = its_irq_startup, + .shutdown = its_irq_shutdown, + .enable = its_irq_enable, + .disable = its_irq_disable, + .ack = its_irq_ack, + .end = its_guest_irq_end, + .set_affinity = its_irq_set_affinity, +}; + /* * How we allocate LPIs: * diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index 9a7d99f..f7cf4e5 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -467,7 +467,7 @@ static void gicv3_mask_irq(struct irq_desc *irqd) gicv3_poke_irq(irqd, GICD_ICENABLER); } -static void gicv3_eoi_irq(struct irq_desc *irqd) +void gicv3_eoi_irq(struct irq_desc *irqd) { /* Lower the priority */ WRITE_SYSREG32(irqd->irq, ICC_EOIR1_EL1); diff --git a/xen/include/asm-arm/gic_v3_defs.h b/xen/include/asm-arm/gic_v3_defs.h index d675a4d..f02e1aae 100644 --- a/xen/include/asm-arm/gic_v3_defs.h +++ b/xen/include/asm-arm/gic_v3_defs.h @@ -189,6 +189,8 @@ struct rdist_prop { DECLARE_PER_CPU(struct rdist, rdist); +void gicv3_eoi_irq(struct irq_desc *irqd); + #endif /* __ASM_ARM_GIC_V3_DEFS_H__ */ /* -- 1.7.9.5