diff options
Diffstat (limited to 'drivers/irqchip')
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 57eaa5a0b1e3..37062ba6704b 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
@@ -155,7 +155,7 @@ static void gic_enable_sre(void) | |||
155 | pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n"); | 155 | pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n"); |
156 | } | 156 | } |
157 | 157 | ||
158 | static void gic_enable_redist(void) | 158 | static void gic_enable_redist(bool enable) |
159 | { | 159 | { |
160 | void __iomem *rbase; | 160 | void __iomem *rbase; |
161 | u32 count = 1000000; /* 1s! */ | 161 | u32 count = 1000000; /* 1s! */ |
@@ -163,20 +163,30 @@ static void gic_enable_redist(void) | |||
163 | 163 | ||
164 | rbase = gic_data_rdist_rd_base(); | 164 | rbase = gic_data_rdist_rd_base(); |
165 | 165 | ||
166 | /* Wake up this CPU redistributor */ | ||
167 | val = readl_relaxed(rbase + GICR_WAKER); | 166 | val = readl_relaxed(rbase + GICR_WAKER); |
168 | val &= ~GICR_WAKER_ProcessorSleep; | 167 | if (enable) |
168 | /* Wake up this CPU redistributor */ | ||
169 | val &= ~GICR_WAKER_ProcessorSleep; | ||
170 | else | ||
171 | val |= GICR_WAKER_ProcessorSleep; | ||
169 | writel_relaxed(val, rbase + GICR_WAKER); | 172 | writel_relaxed(val, rbase + GICR_WAKER); |
170 | 173 | ||
171 | while (readl_relaxed(rbase + GICR_WAKER) & GICR_WAKER_ChildrenAsleep) { | 174 | if (!enable) { /* Check that GICR_WAKER is writeable */ |
172 | count--; | 175 | val = readl_relaxed(rbase + GICR_WAKER); |
173 | if (!count) { | 176 | if (!(val & GICR_WAKER_ProcessorSleep)) |
174 | pr_err_ratelimited("redist didn't wake up...\n"); | 177 | return; /* No PM support in this redistributor */ |
175 | return; | 178 | } |
176 | } | 179 | |
180 | while (count--) { | ||
181 | val = readl_relaxed(rbase + GICR_WAKER); | ||
182 | if (enable ^ (val & GICR_WAKER_ChildrenAsleep)) | ||
183 | break; | ||
177 | cpu_relax(); | 184 | cpu_relax(); |
178 | udelay(1); | 185 | udelay(1); |
179 | }; | 186 | }; |
187 | if (!count) | ||
188 | pr_err_ratelimited("redistributor failed to %s...\n", | ||
189 | enable ? "wakeup" : "sleep"); | ||
180 | } | 190 | } |
181 | 191 | ||
182 | /* | 192 | /* |
@@ -381,7 +391,7 @@ static void gic_cpu_init(void) | |||
381 | if (gic_populate_rdist()) | 391 | if (gic_populate_rdist()) |
382 | return; | 392 | return; |
383 | 393 | ||
384 | gic_enable_redist(); | 394 | gic_enable_redist(true); |
385 | 395 | ||
386 | rbase = gic_data_rdist_sgi_base(); | 396 | rbase = gic_data_rdist_sgi_base(); |
387 | 397 | ||