aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Konovalov <andrey.konovalov@linaro.org>2012-08-22 19:22:29 +0400
committerAndrey Konovalov <andrey.konovalov@linaro.org>2012-08-22 19:22:29 +0400
commit5397eac4679389c02e89b40b69762c6caac0ca85 (patch)
tree742f99e15bc1c3c31effe2fbd9bb63482f720de4
parent7976d0098cb23876730c3d724f3e0ed40c43181d (diff)
parent2c39435458e6d5a42c2508c9f64e607d964a8a61 (diff)
Merge branch 'tracking-tracking-armlt-misc-fixes' into merge-linux-linaro
-rw-r--r--arch/arm/mach-realview/hotplug.c2
-rw-r--r--arch/arm/mach-vexpress/hotplug.c2
-rw-r--r--arch/arm/mm/fault.c13
-rw-r--r--arch/arm/mm/proc-v7-2level.S4
-rw-r--r--arch/arm/mm/proc-v7-3level.S4
-rw-r--r--drivers/cpuidle/coupled.c14
6 files changed, 32 insertions, 7 deletions
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index 57d9efba2956..77b23fa0db92 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -99,7 +99,7 @@ int platform_cpu_kill(unsigned int cpu)
*
* Called with IRQs disabled
*/
-void platform_cpu_die(unsigned int cpu)
+void __cpuinit platform_cpu_die(unsigned int cpu)
{
int spurious = 0;
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
index c504a72b94d6..b0a3f7df70ba 100644
--- a/arch/arm/mach-vexpress/hotplug.c
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -94,7 +94,7 @@ int platform_cpu_kill(unsigned int cpu)
*
* Called with IRQs disabled
*/
-void platform_cpu_die(unsigned int cpu)
+void __cpuinit platform_cpu_die(unsigned int cpu)
{
int spurious = 0;
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index c3bd83450227..44df3649dc13 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -445,8 +445,16 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
if (pud_none(*pud_k))
goto bad_area;
- if (!pud_present(*pud))
+ if (!pud_present(*pud)) {
set_pud(pud, *pud_k);
+ /*
+ * There is a small window during free_pgtables() where the
+ * user *pud entry is 0 but the TLB has not been invalidated
+ * and we get a level 2 (pmd) translation fault caused by the
+ * intermediate TLB caching of the old level 1 (pud) entry.
+ */
+ flush_tlb_kernel_page(addr);
+ }
pmd = pmd_offset(pud, addr);
pmd_k = pmd_offset(pud_k, addr);
@@ -469,8 +477,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
#endif
if (pmd_none(pmd_k[index]))
goto bad_area;
+ if (!pmd_present(pmd[index]))
+ copy_pmd(pmd, pmd_k);
- copy_pmd(pmd, pmd_k);
return 0;
bad_area:
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index fd045e706390..b5ae7b754f9e 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -106,7 +106,9 @@ ENTRY(cpu_v7_set_pte_ext)
ARM( str r3, [r0, #2048]! )
THUMB( add r0, r0, #2048 )
THUMB( str r3, [r0] )
- mcr p15, 0, r0, c7, c10, 1 @ flush_pte
+ mrc p15, 0, r3, c0, c1, 7 @ read ID_MMFR3
+ tst r3, #0xf << 20 @ check the coherent walk bits
+ mcreq p15, 0, r0, c7, c10, 1 @ clean D-cache to PoU
#endif
mov pc, lr
ENDPROC(cpu_v7_set_pte_ext)
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 8de0f1dd1549..6b306057be9d 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -70,7 +70,9 @@ ENTRY(cpu_v7_set_pte_ext)
tst r3, #1 << (55 - 32) @ L_PTE_DIRTY
orreq r2, #L_PTE_RDONLY
1: strd r2, r3, [r0]
- mcr p15, 0, r0, c7, c10, 1 @ flush_pte
+ mrc p15, 0, r3, c0, c1, 7 @ read ID_MMFR3
+ tst r3, #0xf << 20 @ check the coherent walk bits
+ mcreq p15, 0, r0, c7, c10, 1 @ clean D-cache to PoU
#endif
mov pc, lr
ENDPROC(cpu_v7_set_pte_ext)
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c
index 2c9bf2692232..3265844839bf 100644
--- a/drivers/cpuidle/coupled.c
+++ b/drivers/cpuidle/coupled.c
@@ -678,10 +678,22 @@ static int cpuidle_coupled_cpu_notify(struct notifier_block *nb,
int cpu = (unsigned long)hcpu;
struct cpuidle_device *dev;
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_UP_PREPARE:
+ case CPU_DOWN_PREPARE:
+ case CPU_ONLINE:
+ case CPU_DEAD:
+ case CPU_UP_CANCELED:
+ case CPU_DOWN_FAILED:
+ break;
+ default:
+ return NOTIFY_OK;
+ }
+
mutex_lock(&cpuidle_lock);
dev = per_cpu(cpuidle_devices, cpu);
- if (!dev->coupled)
+ if (!dev || !dev->coupled)
goto out;
switch (action & ~CPU_TASKS_FROZEN) {