diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2017-04-18 18:05:48 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2017-04-19 19:40:09 +0200 |
commit | af2a435d240c3969b55a5c48a429a4184faa3941 (patch) | |
tree | f12c1f7055c3f92d0ec4f9583cb96ac33926f779 /target/linux/patches/4.1.39/patch-realtime | |
parent | df940cfc9ea35b7f547297a98f4abda6e5b6a9a2 (diff) |
linux: update 4.1.x to 4.1.39 including rt-patch
Diffstat (limited to 'target/linux/patches/4.1.39/patch-realtime')
-rw-r--r-- | target/linux/patches/4.1.39/patch-realtime | 30260 |
1 files changed, 30260 insertions, 0 deletions
diff --git a/target/linux/patches/4.1.39/patch-realtime b/target/linux/patches/4.1.39/patch-realtime new file mode 100644 index 000000000..52f9bd3d2 --- /dev/null +++ b/target/linux/patches/4.1.39/patch-realtime @@ -0,0 +1,30260 @@ +diff -Nur linux-4.1.39.orig/arch/alpha/mm/fault.c linux-4.1.39/arch/alpha/mm/fault.c +--- linux-4.1.39.orig/arch/alpha/mm/fault.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/alpha/mm/fault.c 2017-04-18 17:56:30.549394649 +0200 +@@ -23,8 +23,7 @@ + #include <linux/smp.h> + #include <linux/interrupt.h> + #include <linux/module.h> +- +-#include <asm/uaccess.h> ++#include <linux/uaccess.h> + + extern void die_if_kernel(char *,struct pt_regs *,long, unsigned long *); + +@@ -107,7 +106,7 @@ + + /* If we're in an interrupt context, or have no user context, + we must not take the fault. */ +- if (!mm || in_atomic()) ++ if (!mm || faulthandler_disabled()) + goto no_context; + + #ifdef CONFIG_ALPHA_LARGE_VMALLOC +diff -Nur linux-4.1.39.orig/arch/arc/include/asm/futex.h linux-4.1.39/arch/arc/include/asm/futex.h +--- linux-4.1.39.orig/arch/arc/include/asm/futex.h 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arc/include/asm/futex.h 2017-04-18 17:56:30.549394649 +0200 +@@ -53,7 +53,7 @@ + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + +- pagefault_disable(); /* implies preempt_disable() */ ++ pagefault_disable(); + + switch (op) { + case FUTEX_OP_SET: +@@ -75,7 +75,7 @@ + ret = -ENOSYS; + } + +- pagefault_enable(); /* subsumes preempt_enable() */ ++ pagefault_enable(); + + if (!ret) { + switch (cmp) { +@@ -104,7 +104,7 @@ + return ret; + } + +-/* Compare-xchg with preemption disabled. ++/* Compare-xchg with pagefaults disabled. + * Notes: + * -Best-Effort: Exchg happens only if compare succeeds. + * If compare fails, returns; leaving retry/looping to upper layers +@@ -121,7 +121,7 @@ + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + +- pagefault_disable(); /* implies preempt_disable() */ ++ pagefault_disable(); + + /* TBD : can use llock/scond */ + __asm__ __volatile__( +@@ -142,7 +142,7 @@ + : "r"(oldval), "r"(newval), "r"(uaddr), "ir"(-EFAULT) + : "cc", "memory"); + +- pagefault_enable(); /* subsumes preempt_enable() */ ++ pagefault_enable(); + + *uval = val; + return val; +diff -Nur linux-4.1.39.orig/arch/arc/mm/fault.c linux-4.1.39/arch/arc/mm/fault.c +--- linux-4.1.39.orig/arch/arc/mm/fault.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arc/mm/fault.c 2017-04-18 17:56:30.549394649 +0200 +@@ -86,7 +86,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (faulthandler_disabled() || !mm) + goto no_context; + + if (user_mode(regs)) +diff -Nur linux-4.1.39.orig/arch/arm/include/asm/cmpxchg.h linux-4.1.39/arch/arm/include/asm/cmpxchg.h +--- linux-4.1.39.orig/arch/arm/include/asm/cmpxchg.h 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/include/asm/cmpxchg.h 2017-04-18 17:56:30.549394649 +0200 +@@ -129,6 +129,8 @@ + + #else /* min ARCH >= ARMv6 */ + ++#define __HAVE_ARCH_CMPXCHG 1 ++ + extern void __bad_cmpxchg(volatile void *ptr, int size); + + /* +diff -Nur linux-4.1.39.orig/arch/arm/include/asm/futex.h linux-4.1.39/arch/arm/include/asm/futex.h +--- linux-4.1.39.orig/arch/arm/include/asm/futex.h 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/include/asm/futex.h 2017-04-18 17:56:30.549394649 +0200 +@@ -93,6 +93,7 @@ + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + return -EFAULT; + ++ preempt_disable(); + __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" + "1: " TUSER(ldr) " %1, [%4]\n" + " teq %1, %2\n" +@@ -104,6 +105,8 @@ + : "cc", "memory"); + + *uval = val; ++ preempt_enable(); ++ + return ret; + } + +@@ -124,7 +127,10 @@ + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + return -EFAULT; + +- pagefault_disable(); /* implies preempt_disable() */ ++#ifndef CONFIG_SMP ++ preempt_disable(); ++#endif ++ pagefault_disable(); + + switch (op) { + case FUTEX_OP_SET: +@@ -146,7 +152,10 @@ + ret = -ENOSYS; + } + +- pagefault_enable(); /* subsumes preempt_enable() */ ++ pagefault_enable(); ++#ifndef CONFIG_SMP ++ preempt_enable(); ++#endif + + if (!ret) { + switch (cmp) { +diff -Nur linux-4.1.39.orig/arch/arm/include/asm/switch_to.h linux-4.1.39/arch/arm/include/asm/switch_to.h +--- linux-4.1.39.orig/arch/arm/include/asm/switch_to.h 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/include/asm/switch_to.h 2017-04-18 17:56:30.549394649 +0200 +@@ -3,6 +3,13 @@ + + #include <linux/thread_info.h> + ++#if defined CONFIG_PREEMPT_RT_FULL && defined CONFIG_HIGHMEM ++void switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p); ++#else ++static inline void ++switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p) { } ++#endif ++ + /* + * For v7 SMP cores running a preemptible kernel we may be pre-empted + * during a TLB maintenance operation, so execute an inner-shareable dsb +@@ -22,6 +29,7 @@ + + #define switch_to(prev,next,last) \ + do { \ ++ switch_kmaps(prev, next); \ + last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ + } while (0) + +diff -Nur linux-4.1.39.orig/arch/arm/include/asm/thread_info.h linux-4.1.39/arch/arm/include/asm/thread_info.h +--- linux-4.1.39.orig/arch/arm/include/asm/thread_info.h 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/include/asm/thread_info.h 2017-04-18 17:56:30.549394649 +0200 +@@ -50,6 +50,7 @@ + struct thread_info { + unsigned long flags; /* low level flags */ + int preempt_count; /* 0 => preemptable, <0 => bug */ ++ int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ + mm_segment_t addr_limit; /* address limit */ + struct task_struct *task; /* main task structure */ + __u32 cpu; /* cpu */ +@@ -147,6 +148,7 @@ + #define TIF_SIGPENDING 0 + #define TIF_NEED_RESCHED 1 + #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ ++#define TIF_NEED_RESCHED_LAZY 3 + #define TIF_UPROBE 7 + #define TIF_SYSCALL_TRACE 8 + #define TIF_SYSCALL_AUDIT 9 +@@ -160,6 +162,7 @@ + #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) + #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) + #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) ++#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) + #define _TIF_UPROBE (1 << TIF_UPROBE) + #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) + #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) +diff -Nur linux-4.1.39.orig/arch/arm/Kconfig linux-4.1.39/arch/arm/Kconfig +--- linux-4.1.39.orig/arch/arm/Kconfig 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/Kconfig 2017-04-18 17:56:30.549394649 +0200 +@@ -31,7 +31,7 @@ + select HARDIRQS_SW_RESEND + select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT) + select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 +- select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL ++ select HAVE_ARCH_JUMP_LABEL if (!XIP_KERNEL && !PREEMPT_RT_BASE) + select HAVE_ARCH_KGDB + select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) + select HAVE_ARCH_TRACEHOOK +@@ -66,6 +66,7 @@ + select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP ++ select HAVE_PREEMPT_LAZY + select HAVE_RCU_TABLE_FREE if (SMP && ARM_LPAE) + select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_SYSCALL_TRACEPOINTS +diff -Nur linux-4.1.39.orig/arch/arm/kernel/asm-offsets.c linux-4.1.39/arch/arm/kernel/asm-offsets.c +--- linux-4.1.39.orig/arch/arm/kernel/asm-offsets.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/kernel/asm-offsets.c 2017-04-18 17:56:30.549394649 +0200 +@@ -65,6 +65,7 @@ + BLANK(); + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); + DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); ++ DEFINE(TI_PREEMPT_LAZY, offsetof(struct thread_info, preempt_lazy_count)); + DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); + DEFINE(TI_TASK, offsetof(struct thread_info, task)); + DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); +diff -Nur linux-4.1.39.orig/arch/arm/kernel/entry-armv.S linux-4.1.39/arch/arm/kernel/entry-armv.S +--- linux-4.1.39.orig/arch/arm/kernel/entry-armv.S 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/kernel/entry-armv.S 2017-04-18 17:56:30.549394649 +0200 +@@ -208,11 +208,18 @@ + #ifdef CONFIG_PREEMPT + get_thread_info tsk + ldr r8, [tsk, #TI_PREEMPT] @ get preempt count +- ldr r0, [tsk, #TI_FLAGS] @ get flags + teq r8, #0 @ if preempt count != 0 ++ bne 1f @ return from exeption ++ ldr r0, [tsk, #TI_FLAGS] @ get flags ++ tst r0, #_TIF_NEED_RESCHED @ if NEED_RESCHED is set ++ blne svc_preempt @ preempt! ++ ++ ldr r8, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count ++ teq r8, #0 @ if preempt lazy count != 0 + movne r0, #0 @ force flags to 0 +- tst r0, #_TIF_NEED_RESCHED ++ tst r0, #_TIF_NEED_RESCHED_LAZY + blne svc_preempt ++1: + #endif + + svc_exit r5, irq = 1 @ return from exception +@@ -227,8 +234,14 @@ + 1: bl preempt_schedule_irq @ irq en/disable is done inside + ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS + tst r0, #_TIF_NEED_RESCHED ++ bne 1b ++ tst r0, #_TIF_NEED_RESCHED_LAZY + reteq r8 @ go again +- b 1b ++ ldr r0, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count ++ teq r0, #0 @ if preempt lazy count != 0 ++ beq 1b ++ ret r8 @ go again ++ + #endif + + __und_fault: +diff -Nur linux-4.1.39.orig/arch/arm/kernel/patch.c linux-4.1.39/arch/arm/kernel/patch.c +--- linux-4.1.39.orig/arch/arm/kernel/patch.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/kernel/patch.c 2017-04-18 17:56:30.549394649 +0200 +@@ -15,7 +15,7 @@ + unsigned int insn; + }; + +-static DEFINE_SPINLOCK(patch_lock); ++static DEFINE_RAW_SPINLOCK(patch_lock); + + static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags) + __acquires(&patch_lock) +@@ -32,7 +32,7 @@ + return addr; + + if (flags) +- spin_lock_irqsave(&patch_lock, *flags); ++ raw_spin_lock_irqsave(&patch_lock, *flags); + else + __acquire(&patch_lock); + +@@ -47,7 +47,7 @@ + clear_fixmap(fixmap); + + if (flags) +- spin_unlock_irqrestore(&patch_lock, *flags); ++ raw_spin_unlock_irqrestore(&patch_lock, *flags); + else + __release(&patch_lock); + } +diff -Nur linux-4.1.39.orig/arch/arm/kernel/process.c linux-4.1.39/arch/arm/kernel/process.c +--- linux-4.1.39.orig/arch/arm/kernel/process.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/kernel/process.c 2017-04-18 17:56:30.549394649 +0200 +@@ -290,6 +290,30 @@ + } + + #ifdef CONFIG_MMU ++/* ++ * CONFIG_SPLIT_PTLOCK_CPUS results in a page->ptl lock. If the lock is not ++ * initialized by pgtable_page_ctor() then a coredump of the vector page will ++ * fail. ++ */ ++static int __init vectors_user_mapping_init_page(void) ++{ ++ struct page *page; ++ unsigned long addr = 0xffff0000; ++ pgd_t *pgd; ++ pud_t *pud; ++ pmd_t *pmd; ++ ++ pgd = pgd_offset_k(addr); ++ pud = pud_offset(pgd, addr); ++ pmd = pmd_offset(pud, addr); ++ page = pmd_page(*(pmd)); ++ ++ pgtable_page_ctor(page); ++ ++ return 0; ++} ++late_initcall(vectors_user_mapping_init_page); ++ + #ifdef CONFIG_KUSER_HELPERS + /* + * The vectors page is always readable from user space for the +diff -Nur linux-4.1.39.orig/arch/arm/kernel/signal.c linux-4.1.39/arch/arm/kernel/signal.c +--- linux-4.1.39.orig/arch/arm/kernel/signal.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/kernel/signal.c 2017-04-18 17:56:30.549394649 +0200 +@@ -568,7 +568,8 @@ + do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) + { + do { +- if (likely(thread_flags & _TIF_NEED_RESCHED)) { ++ if (likely(thread_flags & (_TIF_NEED_RESCHED | ++ _TIF_NEED_RESCHED_LAZY))) { + schedule(); + } else { + if (unlikely(!user_mode(regs))) +diff -Nur linux-4.1.39.orig/arch/arm/kernel/smp.c linux-4.1.39/arch/arm/kernel/smp.c +--- linux-4.1.39.orig/arch/arm/kernel/smp.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/kernel/smp.c 2017-04-18 17:56:30.549394649 +0200 +@@ -213,8 +213,6 @@ + flush_cache_louis(); + local_flush_tlb_all(); + +- clear_tasks_mm_cpumask(cpu); +- + return 0; + } + +@@ -230,6 +228,9 @@ + pr_err("CPU%u: cpu didn't die\n", cpu); + return; + } ++ ++ clear_tasks_mm_cpumask(cpu); ++ + pr_notice("CPU%u: shutdown\n", cpu); + + /* +diff -Nur linux-4.1.39.orig/arch/arm/kernel/unwind.c linux-4.1.39/arch/arm/kernel/unwind.c +--- linux-4.1.39.orig/arch/arm/kernel/unwind.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/kernel/unwind.c 2017-04-18 17:56:30.549394649 +0200 +@@ -93,7 +93,7 @@ + static const struct unwind_idx *__origin_unwind_idx; + extern const struct unwind_idx __stop_unwind_idx[]; + +-static DEFINE_SPINLOCK(unwind_lock); ++static DEFINE_RAW_SPINLOCK(unwind_lock); + static LIST_HEAD(unwind_tables); + + /* Convert a prel31 symbol to an absolute address */ +@@ -201,7 +201,7 @@ + /* module unwind tables */ + struct unwind_table *table; + +- spin_lock_irqsave(&unwind_lock, flags); ++ raw_spin_lock_irqsave(&unwind_lock, flags); + list_for_each_entry(table, &unwind_tables, list) { + if (addr >= table->begin_addr && + addr < table->end_addr) { +@@ -213,7 +213,7 @@ + break; + } + } +- spin_unlock_irqrestore(&unwind_lock, flags); ++ raw_spin_unlock_irqrestore(&unwind_lock, flags); + } + + pr_debug("%s: idx = %p\n", __func__, idx); +@@ -529,9 +529,9 @@ + tab->begin_addr = text_addr; + tab->end_addr = text_addr + text_size; + +- spin_lock_irqsave(&unwind_lock, flags); ++ raw_spin_lock_irqsave(&unwind_lock, flags); + list_add_tail(&tab->list, &unwind_tables); +- spin_unlock_irqrestore(&unwind_lock, flags); ++ raw_spin_unlock_irqrestore(&unwind_lock, flags); + + return tab; + } +@@ -543,9 +543,9 @@ + if (!tab) + return; + +- spin_lock_irqsave(&unwind_lock, flags); ++ raw_spin_lock_irqsave(&unwind_lock, flags); + list_del(&tab->list); +- spin_unlock_irqrestore(&unwind_lock, flags); ++ raw_spin_unlock_irqrestore(&unwind_lock, flags); + + kfree(tab); + } +diff -Nur linux-4.1.39.orig/arch/arm/kvm/arm.c linux-4.1.39/arch/arm/kvm/arm.c +--- linux-4.1.39.orig/arch/arm/kvm/arm.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/kvm/arm.c 2017-04-18 17:56:30.549394649 +0200 +@@ -473,9 +473,9 @@ + + static void vcpu_pause(struct kvm_vcpu *vcpu) + { +- wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu); ++ struct swait_head *wq = kvm_arch_vcpu_wq(vcpu); + +- wait_event_interruptible(*wq, !vcpu->arch.pause); ++ swait_event_interruptible(*wq, !vcpu->arch.pause); + } + + static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu) +diff -Nur linux-4.1.39.orig/arch/arm/kvm/psci.c linux-4.1.39/arch/arm/kvm/psci.c +--- linux-4.1.39.orig/arch/arm/kvm/psci.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/kvm/psci.c 2017-04-18 17:56:30.549394649 +0200 +@@ -68,7 +68,7 @@ + { + struct kvm *kvm = source_vcpu->kvm; + struct kvm_vcpu *vcpu = NULL; +- wait_queue_head_t *wq; ++ struct swait_head *wq; + unsigned long cpu_id; + unsigned long context_id; + phys_addr_t target_pc; +@@ -117,7 +117,7 @@ + smp_mb(); /* Make sure the above is visible */ + + wq = kvm_arch_vcpu_wq(vcpu); +- wake_up_interruptible(wq); ++ swait_wake_interruptible(wq); + + return PSCI_RET_SUCCESS; + } +diff -Nur linux-4.1.39.orig/arch/arm/mach-at91/at91rm9200.c linux-4.1.39/arch/arm/mach-at91/at91rm9200.c +--- linux-4.1.39.orig/arch/arm/mach-at91/at91rm9200.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-at91/at91rm9200.c 2017-04-18 17:56:30.549394649 +0200 +@@ -13,7 +13,6 @@ + #include <linux/of_platform.h> + + #include <asm/mach/arch.h> +-#include <asm/system_misc.h> + + #include "generic.h" + #include "soc.h" +@@ -34,7 +33,6 @@ + + of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); + +- arm_pm_idle = at91rm9200_idle; + at91rm9200_pm_init(); + } + +diff -Nur linux-4.1.39.orig/arch/arm/mach-at91/at91sam9.c linux-4.1.39/arch/arm/mach-at91/at91sam9.c +--- linux-4.1.39.orig/arch/arm/mach-at91/at91sam9.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-at91/at91sam9.c 2017-04-18 17:56:30.549394649 +0200 +@@ -62,8 +62,6 @@ + soc_dev = soc_device_to_device(soc); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); +- +- arm_pm_idle = at91sam9_idle; + } + + static void __init at91sam9_dt_device_init(void) +diff -Nur linux-4.1.39.orig/arch/arm/mach-at91/generic.h linux-4.1.39/arch/arm/mach-at91/generic.h +--- linux-4.1.39.orig/arch/arm/mach-at91/generic.h 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-at91/generic.h 2017-04-18 17:56:30.549394649 +0200 +@@ -11,27 +11,18 @@ + #ifndef _AT91_GENERIC_H + #define _AT91_GENERIC_H + +-#include <linux/of.h> +-#include <linux/reboot.h> +- +- /* Map io */ +-extern void __init at91_map_io(void); +-extern void __init at91_alt_map_io(void); +- +-/* idle */ +-extern void at91rm9200_idle(void); +-extern void at91sam9_idle(void); +- + #ifdef CONFIG_PM + extern void __init at91rm9200_pm_init(void); + extern void __init at91sam9260_pm_init(void); + extern void __init at91sam9g45_pm_init(void); + extern void __init at91sam9x5_pm_init(void); ++extern void __init sama5_pm_init(void); + #else + static inline void __init at91rm9200_pm_init(void) { } + static inline void __init at91sam9260_pm_init(void) { } + static inline void __init at91sam9g45_pm_init(void) { } + static inline void __init at91sam9x5_pm_init(void) { } ++static inline void __init sama5_pm_init(void) { } + #endif + + #endif /* _AT91_GENERIC_H */ +diff -Nur linux-4.1.39.orig/arch/arm/mach-at91/pm.c linux-4.1.39/arch/arm/mach-at91/pm.c +--- linux-4.1.39.orig/arch/arm/mach-at91/pm.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-at91/pm.c 2017-04-18 17:56:30.549394649 +0200 +@@ -31,10 +31,13 @@ + #include <asm/mach/irq.h> + #include <asm/fncpy.h> + #include <asm/cacheflush.h> ++#include <asm/system_misc.h> + + #include "generic.h" + #include "pm.h" + ++static void __iomem *pmc; ++ + /* + * FIXME: this is needed to communicate between the pinctrl driver and + * the PM implementation in the machine. Possibly part of the PM +@@ -85,7 +88,7 @@ + unsigned long scsr; + int i; + +- scsr = at91_pmc_read(AT91_PMC_SCSR); ++ scsr = readl(pmc + AT91_PMC_SCSR); + + /* USB must not be using PLLB */ + if ((scsr & at91_pm_data.uhp_udp_mask) != 0) { +@@ -99,8 +102,7 @@ + + if ((scsr & (AT91_PMC_PCK0 << i)) == 0) + continue; +- +- css = at91_pmc_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; ++ css = readl(pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS; + if (css != AT91_PMC_CSS_SLOW) { + pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); + return 0; +@@ -143,8 +145,8 @@ + flush_cache_all(); + outer_disable(); + +- at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0], +- at91_ramc_base[1], pm_data); ++ at91_suspend_sram_fn(pmc, at91_ramc_base[0], ++ at91_ramc_base[1], pm_data); + + outer_resume(); + } +@@ -348,6 +350,21 @@ + at91_pm_set_standby(standby); + } + ++void at91rm9200_idle(void) ++{ ++ /* ++ * Disable the processor clock. The processor will be automatically ++ * re-enabled by an interrupt or by a reset. ++ */ ++ writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR); ++} ++ ++void at91sam9_idle(void) ++{ ++ writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR); ++ cpu_do_idle(); ++} ++ + static void __init at91_pm_sram_init(void) + { + struct gen_pool *sram_pool; +@@ -394,13 +411,36 @@ + &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); + } + +-static void __init at91_pm_init(void) ++static const struct of_device_id atmel_pmc_ids[] __initconst = { ++ { .compatible = "atmel,at91rm9200-pmc" }, ++ { .compatible = "atmel,at91sam9260-pmc" }, ++ { .compatible = "atmel,at91sam9g45-pmc" }, ++ { .compatible = "atmel,at91sam9n12-pmc" }, ++ { .compatible = "atmel,at91sam9x5-pmc" }, ++ { .compatible = "atmel,sama5d3-pmc" }, ++ { .compatible = "atmel,sama5d2-pmc" }, ++ { /* sentinel */ }, ++}; ++ ++static void __init at91_pm_init(void (*pm_idle)(void)) + { +- at91_pm_sram_init(); ++ struct device_node *pmc_np; + + if (at91_cpuidle_device.dev.platform_data) + platform_device_register(&at91_cpuidle_device); + ++ pmc_np = of_find_matching_node(NULL, atmel_pmc_ids); ++ pmc = of_iomap(pmc_np, 0); ++ if (!pmc) { ++ pr_err("AT91: PM not supported, PMC not found\n"); ++ return; ++ } ++ ++ if (pm_idle) ++ arm_pm_idle = pm_idle; ++ ++ at91_pm_sram_init(); ++ + if (at91_suspend_sram_fn) + suspend_set_ops(&at91_pm_ops); + else +@@ -419,7 +459,7 @@ + at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP; + at91_pm_data.memctrl = AT91_MEMCTRL_MC; + +- at91_pm_init(); ++ at91_pm_init(at91rm9200_idle); + } + + void __init at91sam9260_pm_init(void) +@@ -427,7 +467,7 @@ + at91_dt_ramc(); + at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC; + at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; +- return at91_pm_init(); ++ at91_pm_init(at91sam9_idle); + } + + void __init at91sam9g45_pm_init(void) +@@ -435,7 +475,7 @@ + at91_dt_ramc(); + at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP; + at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; +- return at91_pm_init(); ++ at91_pm_init(at91sam9_idle); + } + + void __init at91sam9x5_pm_init(void) +@@ -443,5 +483,13 @@ + at91_dt_ramc(); + at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; + at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; +- return at91_pm_init(); ++ at91_pm_init(at91sam9_idle); ++} ++ ++void __init sama5_pm_init(void) ++{ ++ at91_dt_ramc(); ++ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; ++ at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; ++ at91_pm_init(NULL); + } +diff -Nur linux-4.1.39.orig/arch/arm/mach-at91/sama5.c linux-4.1.39/arch/arm/mach-at91/sama5.c +--- linux-4.1.39.orig/arch/arm/mach-at91/sama5.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-at91/sama5.c 2017-04-18 17:56:30.549394649 +0200 +@@ -49,7 +49,7 @@ + soc_dev = soc_device_to_device(soc); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); +- at91sam9x5_pm_init(); ++ sama5_pm_init(); + } + + static const char *sama5_dt_board_compat[] __initconst = { +diff -Nur linux-4.1.39.orig/arch/arm/mach-exynos/platsmp.c linux-4.1.39/arch/arm/mach-exynos/platsmp.c +--- linux-4.1.39.orig/arch/arm/mach-exynos/platsmp.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-exynos/platsmp.c 2017-04-18 17:56:30.549394649 +0200 +@@ -231,7 +231,7 @@ + return (void __iomem *)(S5P_VA_SCU); + } + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + static void exynos_secondary_init(unsigned int cpu) + { +@@ -244,8 +244,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -259,7 +259,7 @@ + * Set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * The secondary processor is waiting to be released from +@@ -286,7 +286,7 @@ + + if (timeout == 0) { + printk(KERN_ERR "cpu1 power enable failed"); +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + return -ETIMEDOUT; + } + } +@@ -342,7 +342,7 @@ + * calibrations, then wait for it to finish + */ + fail: +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return pen_release != -1 ? ret : 0; + } +diff -Nur linux-4.1.39.orig/arch/arm/mach-hisi/platmcpm.c linux-4.1.39/arch/arm/mach-hisi/platmcpm.c +--- linux-4.1.39.orig/arch/arm/mach-hisi/platmcpm.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-hisi/platmcpm.c 2017-04-18 17:56:30.549394649 +0200 +@@ -57,7 +57,7 @@ + + static void __iomem *sysctrl, *fabric; + static int hip04_cpu_table[HIP04_MAX_CLUSTERS][HIP04_MAX_CPUS_PER_CLUSTER]; +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + static u32 fabric_phys_addr; + /* + * [0]: bootwrapper physical address +@@ -104,7 +104,7 @@ + if (cluster >= HIP04_MAX_CLUSTERS || cpu >= HIP04_MAX_CPUS_PER_CLUSTER) + return -EINVAL; + +- spin_lock_irq(&boot_lock); ++ raw_spin_lock_irq(&boot_lock); + + if (hip04_cpu_table[cluster][cpu]) + goto out; +@@ -133,7 +133,7 @@ + udelay(20); + out: + hip04_cpu_table[cluster][cpu]++; +- spin_unlock_irq(&boot_lock); ++ raw_spin_unlock_irq(&boot_lock); + + return 0; + } +@@ -149,7 +149,7 @@ + + __mcpm_cpu_going_down(cpu, cluster); + +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP); + hip04_cpu_table[cluster][cpu]--; + if (hip04_cpu_table[cluster][cpu] == 1) { +@@ -162,7 +162,7 @@ + + last_man = hip04_cluster_is_down(cluster); + if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) { +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + /* Since it's Cortex A15, disable L2 prefetching. */ + asm volatile( + "mcr p15, 1, %0, c15, c0, 3 \n\t" +@@ -173,7 +173,7 @@ + hip04_set_snoop_filter(cluster, 0); + __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN); + } else { +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + v7_exit_coherency_flush(louis); + } + +@@ -192,7 +192,7 @@ + cpu >= HIP04_MAX_CPUS_PER_CLUSTER); + + count = TIMEOUT_MSEC / POLL_MSEC; +- spin_lock_irq(&boot_lock); ++ raw_spin_lock_irq(&boot_lock); + for (tries = 0; tries < count; tries++) { + if (hip04_cpu_table[cluster][cpu]) { + ret = -EBUSY; +@@ -202,10 +202,10 @@ + data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster)); + if (data & CORE_WFI_STATUS(cpu)) + break; +- spin_unlock_irq(&boot_lock); ++ raw_spin_unlock_irq(&boot_lock); + /* Wait for clean L2 when the whole cluster is down. */ + msleep(POLL_MSEC); +- spin_lock_irq(&boot_lock); ++ raw_spin_lock_irq(&boot_lock); + } + if (tries >= count) + goto err; +@@ -220,10 +220,10 @@ + } + if (tries >= count) + goto err; +- spin_unlock_irq(&boot_lock); ++ raw_spin_unlock_irq(&boot_lock); + return 0; + err: +- spin_unlock_irq(&boot_lock); ++ raw_spin_unlock_irq(&boot_lock); + return ret; + } + +@@ -235,10 +235,10 @@ + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + if (!hip04_cpu_table[cluster][cpu]) + hip04_cpu_table[cluster][cpu] = 1; +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static void __naked hip04_mcpm_power_up_setup(unsigned int affinity_level) +diff -Nur linux-4.1.39.orig/arch/arm/mach-omap2/gpio.c linux-4.1.39/arch/arm/mach-omap2/gpio.c +--- linux-4.1.39.orig/arch/arm/mach-omap2/gpio.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-omap2/gpio.c 2017-04-18 17:56:30.549394649 +0200 +@@ -130,7 +130,6 @@ + } + + pwrdm = omap_hwmod_get_pwrdm(oh); +- pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); + + pdev = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata)); + kfree(pdata); +diff -Nur linux-4.1.39.orig/arch/arm/mach-omap2/omap-smp.c linux-4.1.39/arch/arm/mach-omap2/omap-smp.c +--- linux-4.1.39.orig/arch/arm/mach-omap2/omap-smp.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-omap2/omap-smp.c 2017-04-18 17:56:30.549394649 +0200 +@@ -43,7 +43,7 @@ + /* SCU base address */ + static void __iomem *scu_base; + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + void __iomem *omap4_get_scu_base(void) + { +@@ -74,8 +74,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -89,7 +89,7 @@ + * Set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * Update the AuxCoreBoot0 with boot state for secondary core. +@@ -166,7 +166,7 @@ + * Now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return 0; + } +diff -Nur linux-4.1.39.orig/arch/arm/mach-omap2/powerdomain.c linux-4.1.39/arch/arm/mach-omap2/powerdomain.c +--- linux-4.1.39.orig/arch/arm/mach-omap2/powerdomain.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-omap2/powerdomain.c 2017-04-18 17:56:30.553394804 +0200 +@@ -1166,43 +1166,3 @@ + return count; + } + +-/** +- * pwrdm_can_ever_lose_context - can this powerdomain ever lose context? +- * @pwrdm: struct powerdomain * +- * +- * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain +- * can lose either memory or logic context or if @pwrdm is invalid, or +- * returns 0 otherwise. This function is not concerned with how the +- * powerdomain registers are programmed (i.e., to go off or not); it's +- * concerned with whether it's ever possible for this powerdomain to +- * go off while some other part of the chip is active. This function +- * assumes that every powerdomain can go to either ON or INACTIVE. +- */ +-bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm) +-{ +- int i; +- +- if (!pwrdm) { +- pr_debug("powerdomain: %s: invalid powerdomain pointer\n", +- __func__); +- return 1; +- } +- +- if (pwrdm->pwrsts & PWRSTS_OFF) +- return 1; +- +- if (pwrdm->pwrsts & PWRSTS_RET) { +- if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF) +- return 1; +- +- for (i = 0; i < pwrdm->banks; i++) +- if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF) +- return 1; +- } +- +- for (i = 0; i < pwrdm->banks; i++) +- if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF) +- return 1; +- +- return 0; +-} +diff -Nur linux-4.1.39.orig/arch/arm/mach-omap2/powerdomain.h linux-4.1.39/arch/arm/mach-omap2/powerdomain.h +--- linux-4.1.39.orig/arch/arm/mach-omap2/powerdomain.h 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-omap2/powerdomain.h 2017-04-18 17:56:30.553394804 +0200 +@@ -244,7 +244,6 @@ + int pwrdm_pre_transition(struct powerdomain *pwrdm); + int pwrdm_post_transition(struct powerdomain *pwrdm); + int pwrdm_get_context_loss_count(struct powerdomain *pwrdm); +-bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); + + extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 state); + +diff -Nur linux-4.1.39.orig/arch/arm/mach-prima2/platsmp.c linux-4.1.39/arch/arm/mach-prima2/platsmp.c +--- linux-4.1.39.orig/arch/arm/mach-prima2/platsmp.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-prima2/platsmp.c 2017-04-18 17:56:30.553394804 +0200 +@@ -22,7 +22,7 @@ + + static void __iomem *clk_base; + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + static void sirfsoc_secondary_init(unsigned int cpu) + { +@@ -36,8 +36,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static const struct of_device_id clk_ids[] = { +@@ -75,7 +75,7 @@ + /* make sure write buffer is drained */ + mb(); + +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * The secondary processor is waiting to be released from +@@ -107,7 +107,7 @@ + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return pen_release != -1 ? -ENOSYS : 0; + } +diff -Nur linux-4.1.39.orig/arch/arm/mach-qcom/platsmp.c linux-4.1.39/arch/arm/mach-qcom/platsmp.c +--- linux-4.1.39.orig/arch/arm/mach-qcom/platsmp.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-qcom/platsmp.c 2017-04-18 17:56:30.553394804 +0200 +@@ -46,7 +46,7 @@ + + extern void secondary_startup_arm(void); + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + #ifdef CONFIG_HOTPLUG_CPU + static void __ref qcom_cpu_die(unsigned int cpu) +@@ -60,8 +60,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static int scss_release_secondary(unsigned int cpu) +@@ -284,7 +284,7 @@ + * set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * Send the secondary CPU a soft interrupt, thereby causing +@@ -297,7 +297,7 @@ + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ +- spin_unlock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + + return ret; + } +diff -Nur linux-4.1.39.orig/arch/arm/mach-spear/platsmp.c linux-4.1.39/arch/arm/mach-spear/platsmp.c +--- linux-4.1.39.orig/arch/arm/mach-spear/platsmp.c 2017-03-13 21:04:36.000000000 +0100 ++++ linux-4.1.39/arch/arm/mach-spear/platsmp.c 2017-04-18 17:56:30.553394804 +0200 +@@ -32,7 +32,7 @@ + sync_cache_w(&pen_release); + } + +-static DEFINE_SPINLOCK(boot_lock); ++static DEFINE_RAW_SPINLOCK(boot_lock); + + static void __iomem *scu_base = IOMEM(VA_SCU_BASE); + +@@ -47,8 +47,8 @@ + /* + * Synchronise with the boot thread. + */ +- spin_lock(&boot_lock); +- spin_unlock(&boot_lock); ++ raw_spin_lock(&boot_lock); ++ raw_spin_unlock(&boot_lock); + } + + static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -59,7 +59,7 @@ + * set synchronisation state between this boot processor + * and the secondary one + */ +- spin_lock(&boot_lock); ++ raw_spin_lock(&boot_lock); + + /* + * The secondary processor is waiting to be released from +@@ -84,7 +84,7 @@ + * now the secondary core is starting up let it run its |