[PATCH V3 1/5] ARM: tegra: add pending SGI checking API
Colin Cross
ccross at android.com
Mon Dec 17 21:42:24 EST 2012
On Mon, Dec 17, 2012 at 6:30 PM, Joseph Lo <josephl at nvidia.com> wrote:
> The "powered-down" CPU idle mode of Tegra cut off the vdd_cpu rail, it
> include the power of GIC. That caused the SGI (Software Generated
> Interrupt) been lost. Because the SGI can't wake up the CPU that in
> the "powered-down" CPU idle mode. We need to check if there is any
> pending SGI when go into "powered-down" CPU idle mode. This is important
> especially when applying the coupled cpuidle framework into "power-down"
> cpuidle dirver. Because the coupled cpuidle framework may have the
> chance that misses IPI_SINGLE_FUNC handling sometimes.
This problem exists for any GIC-based SoC, and needs to be fixed in
gic_cpu_save or gic_dist_save, whichever one loses the interrupt.
> For the PPI or SPI, something like the legacy peripheral interrupt. It
> still can be maintained by Tegra legacy interrupt controller. If there
> is any pending PPI or SPI when CPU in "powered-down" CPU idle mode. The
> CPU can be woken up immediately. So we don't need to take care the same
> situation for PPI or SPI.
>
> Signed-off-by: Joseph Lo <josephl at nvidia.com>
> ---
> V3:
> * move the static mapping of GIC addr into tegra_pending_sgi
> V2:
> * new in V2
> ---
> arch/arm/mach-tegra/irq.c | 15 +++++++++++++++
> arch/arm/mach-tegra/irq.h | 22 ++++++++++++++++++++++
> 2 files changed, 37 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-tegra/irq.h
>
> diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
> index b7886f1..c9976e3 100644
> --- a/arch/arm/mach-tegra/irq.c
> +++ b/arch/arm/mach-tegra/irq.c
> @@ -45,6 +45,8 @@
>
> #define FIRST_LEGACY_IRQ 32
>
> +#define SGI_MASK 0xFFFF
> +
> static int num_ictlrs;
>
> static void __iomem *ictlr_reg_base[] = {
> @@ -55,6 +57,19 @@ static void __iomem *ictlr_reg_base[] = {
> IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
> };
>
> +bool tegra_pending_sgi(void)
> +{
> + u32 pending_set;
> + void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
> +
> + pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET);
> +
> + if (pending_set & SGI_MASK)
> + return true;
> +
> + return false;
> +}
> +
> static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
> {
> void __iomem *base;
> diff --git a/arch/arm/mach-tegra/irq.h b/arch/arm/mach-tegra/irq.h
> new file mode 100644
> index 0000000..5142649
> --- /dev/null
> +++ b/arch/arm/mach-tegra/irq.h
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __TEGRA_IRQ_H
> +#define __TEGRA_IRQ_H
> +
> +bool tegra_pending_sgi(void);
> +
> +#endif
> --
> 1.7.0.4
>
More information about the linux-arm-kernel
mailing list