Skip to content

Commit

Permalink
irqchip: gic-v3: Refactor gic_enable_redist to support both enabling …
Browse files Browse the repository at this point in the history
…and disabling

Currently gic_enable_redist configures the redistributors to never
assert WakeRequest signal. However when powering down the processors
with wake-up enabled(i.e suspend), we need to configure it to assert
that signal.

This patch extends gic_enable_redist so that the redistributor can be
configure to assert WakeRequest and hold interrupts as pending. This is
useful in suspending the processors.

This patch also adds check to make sure GICR_WAKER is accessible when
configuring it.

Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
[maz: removed reference to GICD_CTLR.DS and added read-back of
      GICR_WAKER to check that it is not RAZ/WI]
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Link: https://lkml.kernel.org/r/1409065415-20176-2-git-send-email-sudeep.holla@arm.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
  • Loading branch information
Sudeep Holla authored and Jason Cooper committed Sep 14, 2014
1 parent 3228950 commit a2c2251
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions drivers/irqchip/irq-gic-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,28 +155,38 @@ static void gic_enable_sre(void)
pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n");
}

static void gic_enable_redist(void)
static void gic_enable_redist(bool enable)
{
void __iomem *rbase;
u32 count = 1000000; /* 1s! */
u32 val;

rbase = gic_data_rdist_rd_base();

/* Wake up this CPU redistributor */
val = readl_relaxed(rbase + GICR_WAKER);
val &= ~GICR_WAKER_ProcessorSleep;
if (enable)
/* Wake up this CPU redistributor */
val &= ~GICR_WAKER_ProcessorSleep;
else
val |= GICR_WAKER_ProcessorSleep;
writel_relaxed(val, rbase + GICR_WAKER);

while (readl_relaxed(rbase + GICR_WAKER) & GICR_WAKER_ChildrenAsleep) {
count--;
if (!count) {
pr_err_ratelimited("redist didn't wake up...\n");
return;
}
if (!enable) { /* Check that GICR_WAKER is writeable */
val = readl_relaxed(rbase + GICR_WAKER);
if (!(val & GICR_WAKER_ProcessorSleep))
return; /* No PM support in this redistributor */
}

while (count--) {
val = readl_relaxed(rbase + GICR_WAKER);
if (enable ^ (val & GICR_WAKER_ChildrenAsleep))
break;
cpu_relax();
udelay(1);
};
if (!count)
pr_err_ratelimited("redistributor failed to %s...\n",
enable ? "wakeup" : "sleep");
}

/*
Expand Down Expand Up @@ -381,7 +391,7 @@ static void gic_cpu_init(void)
if (gic_populate_rdist())
return;

gic_enable_redist();
gic_enable_redist(true);

rbase = gic_data_rdist_sgi_base();

Expand Down

0 comments on commit a2c2251

Please sign in to comment.