[linux-yocto] [PATCH 32/87] LSI axm55xx: Fix boot issues with PREMPT_RT kernel

Bruce Ashfield bruce.ashfield at windriver.com
Mon May 27 12:05:35 PDT 2013


On 13-05-27 12:56 PM, Paul Butler wrote:
> From: David Mercado <david.mercado at windriver.com>
>
> Modified arch/arm/mach-axxia/axxia-gic.c to to handle the slightly different
> way in which a preempt_rt kernel manipulates the Axxia GIC API during boot.
> Also updated arch/arm/configs/lsisim_defconfig to set the base level of
> prempt_rt to CONFIG_PREEMPT_RTB.  The preempt_rt kernel must be set with

This doesn't match the patch ...

Bruce

> a minimal preempt model, to enable CONFIG_GENERIC_LOCKBREAK, which in turn
> allows spinlocks to work correctly across multiple clusters.
>
> Signed-off-by: David Mercado <david.mercado at windriver.com>
> Signed-off-by: Paul Butler <paul.butler at windriver.com>
> ---
>   arch/arm/mach-axxia/axxia-gic.c | 54 +++++++++++++++++++++++++++++++++--------
>   1 file changed, 44 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm/mach-axxia/axxia-gic.c b/arch/arm/mach-axxia/axxia-gic.c
> index 058b837..20d04ea 100644
> --- a/arch/arm/mach-axxia/axxia-gic.c
> +++ b/arch/arm/mach-axxia/axxia-gic.c
> @@ -155,9 +155,11 @@ static void gic_mask_irq(struct irq_data *d)
>   	if (irqid >= 1020)
>   		return;
>
> -	/* We should never be disabling the AXM IPI interrupts. */
> -	if ((irqid >= IPI0_CPU0) && (irqid < MAX_AXM_IPI_NUM))
> +	/* Deal with PPI interrupts directly. */
> +	if (irqid > 16 && irqid < 32) {
> +		_gic_mask_irq(d);
>   		return;
> +	}
>
>   	/*
>   	 * If the cpu that this interrupt is assigned to falls within
> @@ -182,22 +184,54 @@ static void gic_mask_irq(struct irq_data *d)
>   	}
>   }
>
> -static void gic_unmask_irq(struct irq_data *d)
> +static void _gic_unmask_irq(void *arg)
>   {
> +	struct irq_data *d = (struct irq_data *)arg;
>   	u32 mask = 1 << (gic_irq(d) % 32);
>
> -	/*
> -	 * No need to run this at all clusters, since the kernel
> -	 * also calls gic_set_affinity when unmasking interrupts.
> -	 * In that routine we also unmask the interrupt, so doing
> -	 * it here would be redundant.
> -	 */
>   	raw_spin_lock(&irq_controller_lock);
>   	writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET
> -			+ (gic_irq(d) / 32) * 4);
> +				+ (gic_irq(d) / 32) * 4);
>   	raw_spin_unlock(&irq_controller_lock);
>   }
>
> +static void gic_unmask_irq(struct irq_data *d)
> +{
> +	u32 pcpu = cpu_logical_map(smp_processor_id());
> +	u32 irqid = gic_irq(d);
> +
> +	if (irqid >= 1020)
> +		return;
> +
> +	/* Deal with PPI interrupts directly. */
> +	if (irqid > 15 && irqid < 32) {
> +		_gic_unmask_irq(d);
> +		return;
> +	}
> +
> +	/*
> +	 * If the cpu that this interrupt is assigned to falls within
> +	 * the same cluster as the cpu we're currently running on, do
> +	 * the IRQ masking directly. Otherwise, use the IPI mechanism
> +	 * to remotely do the masking.
> +	 */
> +	if ((cpu_logical_map(irq_cpuid[irqid]) / 4) == (pcpu / 4)) {
> +		_gic_unmask_irq(d);
> +	} else {
> +		/*
> +		 * We are running here with local interrupts
> +		 * disabled. Temporarily re-enable them to
> +		 * avoid possible deadlock when calling
> +		 * smp_call_function_single().
> +		 */
> +		local_irq_enable();
> +		smp_call_function_single(irq_cpuid[irqid],
> +					 _gic_unmask_irq,
> +					 d, 1);
> +		local_irq_disable();
> +	}
> +}
> +
>   static void gic_eoi_irq(struct irq_data *d)
>   {
>   	/*
>




More information about the linux-yocto mailing list