summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-03-09 14:41:27 +0100
committerSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-03-09 14:41:27 +0100
commit3300e9f53a238b533ecbd8857d4c93f65132bafc (patch)
tree2a7910f591b99a35d98e7aa92d8b6c327e315270
parentee504eaedb9779b0e95b5925f3bbc9e0ead0282a (diff)
download4.12-rt-patches-3300e9f53a238b533ecbd8857d4c93f65132bafc.tar.gz
[ANNOUNCE] 4.4.4-rt11
Dear RT folks! I'm pleased to announce the v4.4.4-rt11 patch set. Changes since v4.4.4-rt10: - A compile error has been fixed in conjunction with the latency tracer. - AT91 got a little better. A larger patch series by Boris Brezillon has been merged. That means SAMA5 boots now. There is one warning left about invoking free_irq() twice. I would be glad about some feedback from pre-SAMA5 SoC. Those which share UART and timer interrupt. It seems that that one I have here does not do this anymore. - A patch on top the AT91 series to avoid two warning while switching from period to oneshow mode. - Daniel Wagner refurbished the swait patches. This relase contains now what is queued for v4.6 in the TIP tree. Only RT uses `completion' based on swait. Based on the current implementation you will see a warning if complete_all() in invoked on more than two waiters. Please report if see this. Known issues: - CPU hotplug got a little better but can deadlock. The delta patch against 4.4.4-rt10 is appended below and can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.4/incr/patch-4.4.4-rt10-rt11.patch.xz You can get this release via the git tree at: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git v4.4.4-rt11 The RT patch against 4.4.4 can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.4/patch-4.4.4-rt11.patch.xz The split quilt queue is available at: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.4/patches-4.4.4-rt11.tar.xz Sebastian Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-rw-r--r--patches/0001-clk-at91-make-use-of-syscon-to-share-PMC-registers-i.patch121
-rw-r--r--patches/0001-wait.-ch-Introduce-the-simple-waitqueue-swait-implem.patch360
-rw-r--r--patches/0002-clk-at91-make-use-of-syscon-regmap-internally.patch3252
-rw-r--r--patches/0002-kbuild-Add-option-to-turn-incompatible-pointer-check.patch52
-rw-r--r--patches/0003-KVM-Use-simple-waitqueue-for-vcpu-wq.patch (renamed from patches/KVM-use-simple-waitqueue-for-vcpu-wq.patch)194
-rw-r--r--patches/0003-clk-at91-remove-IRQ-handling-and-use-polling.patch1033
-rw-r--r--patches/0004-clk-at91-pmc-merge-at91_pmc_init-in-atmel_pmc_probe.patch70
-rw-r--r--patches/0004-rcu-Do-not-call-rcu_nocb_gp_cleanup-while-holding-rn.patch190
-rw-r--r--patches/0005-clk-at91-pmc-move-pmc-structures-to-C-file.patch52
-rw-r--r--patches/0005-rcu-Use-simple-wait-queues-where-possible-in-rcutree.patch310
-rw-r--r--patches/0006-ARM-at91-pm-simply-call-at91_pm_init.patch41
-rw-r--r--patches/0007-ARM-at91-pm-find-and-remap-the-pmc.patch90
-rw-r--r--patches/0008-ARM-at91-pm-move-idle-functions-to-pm.c.patch201
-rw-r--r--patches/0009-ARM-at91-remove-useless-includes-and-function-protot.patch30
-rw-r--r--patches/0010-usb-gadget-atmel-access-the-PMC-using-regmap.patch75
-rw-r--r--patches/0011-clk-at91-pmc-drop-at91_pmc_base.patch69
-rw-r--r--patches/0012-clk-at91-pmc-remove-useless-capacities-handling.patch155
-rw-r--r--patches/0013-clk-at91-remove-useless-includes.patch129
-rw-r--r--patches/KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch4
-rw-r--r--patches/at91_dont_enable_disable_clock.patch91
-rw-r--r--patches/block-blk-mq-use-swait.patch10
-rw-r--r--patches/clocksource-tclib-allow-higher-clockrates.patch28
-rw-r--r--patches/completion-use-simple-wait-queues.patch60
-rw-r--r--patches/genirq-update-irq_set_irqchip_state-documentation.patch3
-rw-r--r--patches/latency-hist.patch7
-rw-r--r--patches/localversion.patch4
-rw-r--r--patches/mm--rt--Fix-generic-kmap_atomic-for-RT.patch (renamed from patches/mm--rt--Fix-generic-kmap_atomic-for-RT)0
-rw-r--r--patches/net__Make_synchronize-rcu_expedited_conditional-on-non-rt.patch (renamed from patches/net__Make_synchronize-rcu_expedited_conditional-on-non-rt)0
-rw-r--r--patches/rcu-Eliminate-softirq-processing-from-rcutree.patch6
-rw-r--r--patches/rcu-disable-more-spots-of-rcu_bh.patch4
-rw-r--r--patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch12
-rw-r--r--patches/rcu-more-swait-conversions.patch212
-rw-r--r--patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch (renamed from patches/rtmutex--Handle-non-enqueued-waiters-gracefully)0
-rw-r--r--patches/series30
-rw-r--r--patches/wait-simple-implementation.patch362
-rw-r--r--patches/work-simple-Simple-work-queue-implemenation.patch12
36 files changed, 6578 insertions, 691 deletions
diff --git a/patches/0001-clk-at91-make-use-of-syscon-to-share-PMC-registers-i.patch b/patches/0001-clk-at91-make-use-of-syscon-to-share-PMC-registers-i.patch
new file mode 100644
index 00000000000000..62ad706a6aba34
--- /dev/null
+++ b/patches/0001-clk-at91-make-use-of-syscon-to-share-PMC-registers-i.patch
@@ -0,0 +1,121 @@
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Fri, 5 Sep 2014 09:54:13 +0200
+Subject: [PATCH 01/13] clk: at91: make use of syscon to share PMC registers in
+ several drivers
+
+The PMC block is providing several functionnalities:
+ - system clk management
+ - cpuidle
+ - platform suspend
+
+Replace the void __iomem *regs field by a regmap (retrieved using syscon)
+so that we can later share the regmap across several drivers without
+exporting a new specific API or a global void __iomem * variable.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Acked-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ arch/arm/mach-at91/Kconfig | 1 +
+ drivers/clk/at91/pmc.c | 12 ++++++++----
+ drivers/clk/at91/pmc.h | 11 ++++++++---
+ 3 files changed, 17 insertions(+), 7 deletions(-)
+
+--- a/arch/arm/mach-at91/Kconfig
++++ b/arch/arm/mach-at91/Kconfig
+@@ -99,6 +99,7 @@ config HAVE_AT91_USB_CLK
+ config COMMON_CLK_AT91
+ bool
+ select COMMON_CLK
++ select MFD_SYSCON
+
+ config HAVE_AT91_SMD
+ bool
+--- a/drivers/clk/at91/pmc.c
++++ b/drivers/clk/at91/pmc.c
+@@ -19,6 +19,7 @@
+ #include <linux/irqchip/chained_irq.h>
+ #include <linux/irqdomain.h>
+ #include <linux/of_irq.h>
++#include <linux/mfd/syscon.h>
+
+ #include <asm/proc-fns.h>
+
+@@ -223,6 +224,7 @@ static const struct at91_pmc_caps sama5d
+ };
+
+ static struct at91_pmc *__init at91_pmc_init(struct device_node *np,
++ struct regmap *regmap,
+ void __iomem *regbase, int virq,
+ const struct at91_pmc_caps *caps)
+ {
+@@ -238,7 +240,7 @@ static struct at91_pmc *__init at91_pmc_
+ return NULL;
+
+ spin_lock_init(&pmc->lock);
+- pmc->regbase = regbase;
++ pmc->regmap = regmap;
+ pmc->virq = virq;
+ pmc->caps = caps;
+
+@@ -394,16 +396,18 @@ static void __init of_at91_pmc_setup(str
+ void (*clk_setup)(struct device_node *, struct at91_pmc *);
+ const struct of_device_id *clk_id;
+ void __iomem *regbase = of_iomap(np, 0);
++ struct regmap *regmap;
+ int virq;
+
+- if (!regbase)
+- return;
++ regmap = syscon_node_to_regmap(np);
++ if (IS_ERR(regmap))
++ panic("Could not retrieve syscon regmap");
+
+ virq = irq_of_parse_and_map(np, 0);
+ if (!virq)
+ return;
+
+- pmc = at91_pmc_init(np, regbase, virq, caps);
++ pmc = at91_pmc_init(np, regmap, regbase, virq, caps);
+ if (!pmc)
+ return;
+ for_each_child_of_node(np, childnp) {
+--- a/drivers/clk/at91/pmc.h
++++ b/drivers/clk/at91/pmc.h
+@@ -14,6 +14,7 @@
+
+ #include <linux/io.h>
+ #include <linux/irqdomain.h>
++#include <linux/regmap.h>
+ #include <linux/spinlock.h>
+
+ struct clk_range {
+@@ -28,7 +29,7 @@ struct at91_pmc_caps {
+ };
+
+ struct at91_pmc {
+- void __iomem *regbase;
++ struct regmap *regmap;
+ int virq;
+ spinlock_t lock;
+ const struct at91_pmc_caps *caps;
+@@ -48,12 +49,16 @@ static inline void pmc_unlock(struct at9
+
+ static inline u32 pmc_read(struct at91_pmc *pmc, int offset)
+ {
+- return readl(pmc->regbase + offset);
++ unsigned int ret = 0;
++
++ regmap_read(pmc->regmap, offset, &ret);
++
++ return ret;
+ }
+
+ static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value)
+ {
+- writel(value, pmc->regbase + offset);
++ regmap_write(pmc->regmap, offset, value);
+ }
+
+ int of_at91_get_clk_range(struct device_node *np, const char *propname,
diff --git a/patches/0001-wait.-ch-Introduce-the-simple-waitqueue-swait-implem.patch b/patches/0001-wait.-ch-Introduce-the-simple-waitqueue-swait-implem.patch
new file mode 100644
index 00000000000000..d0dade7f816510
--- /dev/null
+++ b/patches/0001-wait.-ch-Introduce-the-simple-waitqueue-swait-implem.patch
@@ -0,0 +1,360 @@
+From: "Peter Zijlstra (Intel)" <peterz@infradead.org>
+Date: Fri, 19 Feb 2016 09:46:37 +0100
+Subject: [PATCH 1/5] wait.[ch]: Introduce the simple waitqueue (swait)
+ implementation
+
+The existing wait queue support has support for custom wake up call
+backs, wake flags, wake key (passed to call back) and exclusive
+flags that allow wakers to be tagged as exclusive, for limiting
+the number of wakers.
+
+In a lot of cases, none of these features are used, and hence we
+can benefit from a slimmed down version that lowers memory overhead
+and reduces runtime overhead.
+
+The concept originated from -rt, where waitqueues are a constant
+source of trouble, as we can't convert the head lock to a raw
+spinlock due to fancy and long lasting callbacks.
+
+With the removal of custom callbacks, we can use a raw lock for
+queue list manipulations, hence allowing the simple wait support
+to be used in -rt.
+
+[Patch is from PeterZ which is based on Thomas version. Commit message is
+ written by Paul G.
+ Daniel: - Fixed some compile issues
+ - Added non-lazy implementation of swake_up_locked as suggested
+ by Boqun Feng.]
+
+Originally-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: linux-rt-users@vger.kernel.org
+Cc: Boqun Feng <boqun.feng@gmail.com>
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Link: http://lkml.kernel.org/r/1455871601-27484-2-git-send-email-wagi@monom.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+---
+ include/linux/swait.h | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ kernel/sched/Makefile | 2
+ kernel/sched/swait.c | 123 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 296 insertions(+), 1 deletion(-)
+ create mode 100644 include/linux/swait.h
+ create mode 100644 kernel/sched/swait.c
+
+--- /dev/null
++++ b/include/linux/swait.h
+@@ -0,0 +1,172 @@
++#ifndef _LINUX_SWAIT_H
++#define _LINUX_SWAIT_H
++
++#include <linux/list.h>
++#include <linux/stddef.h>
++#include <linux/spinlock.h>
++#include <asm/current.h>
++
++/*
++ * Simple wait queues
++ *
++ * While these are very similar to the other/complex wait queues (wait.h) the
++ * most important difference is that the simple waitqueue allows for
++ * deterministic behaviour -- IOW it has strictly bounded IRQ and lock hold
++ * times.
++ *
++ * In order to make this so, we had to drop a fair number of features of the
++ * other waitqueue code; notably:
++ *
++ * - mixing INTERRUPTIBLE and UNINTERRUPTIBLE sleeps on the same waitqueue;
++ * all wakeups are TASK_NORMAL in order to avoid O(n) lookups for the right
++ * sleeper state.
++ *
++ * - the exclusive mode; because this requires preserving the list order
++ * and this is hard.
++ *
++ * - custom wake functions; because you cannot give any guarantees about
++ * random code.
++ *
++ * As a side effect of this; the data structures are slimmer.
++ *
++ * One would recommend using this wait queue where possible.
++ */
++
++struct task_struct;
++
++struct swait_queue_head {
++ raw_spinlock_t lock;
++ struct list_head task_list;
++};
++
++struct swait_queue {
++ struct task_struct *task;
++ struct list_head task_list;
++};
++
++#define __SWAITQUEUE_INITIALIZER(name) { \
++ .task = current, \
++ .task_list = LIST_HEAD_INIT((name).task_list), \
++}
++
++#define DECLARE_SWAITQUEUE(name) \
++ struct swait_queue name = __SWAITQUEUE_INITIALIZER(name)
++
++#define __SWAIT_QUEUE_HEAD_INITIALIZER(name) { \
++ .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \
++ .task_list = LIST_HEAD_INIT((name).task_list), \
++}
++
++#define DECLARE_SWAIT_QUEUE_HEAD(name) \
++ struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INITIALIZER(name)
++
++extern void __init_swait_queue_head(struct swait_queue_head *q, const char *name,
++ struct lock_class_key *key);
++
++#define init_swait_queue_head(q) \
++ do { \
++ static struct lock_class_key __key; \
++ __init_swait_queue_head((q), #q, &__key); \
++ } while (0)
++
++#ifdef CONFIG_LOCKDEP
++# define __SWAIT_QUEUE_HEAD_INIT_ONSTACK(name) \
++ ({ init_swait_queue_head(&name); name; })
++# define DECLARE_SWAIT_QUEUE_HEAD_ONSTACK(name) \
++ struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INIT_ONSTACK(name)
++#else
++# define DECLARE_SWAIT_QUEUE_HEAD_ONSTACK(name) \
++ DECLARE_SWAIT_QUEUE_HEAD(name)
++#endif
++
++static inline int swait_active(struct swait_queue_head *q)
++{
++ return !list_empty(&q->task_list);
++}
++
++extern void swake_up(struct swait_queue_head *q);
++extern void swake_up_all(struct swait_queue_head *q);
++extern void swake_up_locked(struct swait_queue_head *q);
++
++extern void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait);
++extern void prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait, int state);
++extern long prepare_to_swait_event(struct swait_queue_head *q, struct swait_queue *wait, int state);
++
++extern void __finish_swait(struct swait_queue_head *q, struct swait_queue *wait);
++extern void finish_swait(struct swait_queue_head *q, struct swait_queue *wait);
++
++/* as per ___wait_event() but for swait, therefore "exclusive == 0" */
++#define ___swait_event(wq, condition, state, ret, cmd) \
++({ \
++ struct swait_queue __wait; \
++ long __ret = ret; \
++ \
++ INIT_LIST_HEAD(&__wait.task_list); \
++ for (;;) { \
++ long __int = prepare_to_swait_event(&wq, &__wait, state);\
++ \
++ if (condition) \
++ break; \
++ \
++ if (___wait_is_interruptible(state) && __int) { \
++ __ret = __int; \
++ break; \
++ } \
++ \
++ cmd; \
++ } \
++ finish_swait(&wq, &__wait); \
++ __ret; \
++})
++
++#define __swait_event(wq, condition) \
++ (void)___swait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, \
++ schedule())
++
++#define swait_event(wq, condition) \
++do { \
++ if (condition) \
++ break; \
++ __swait_event(wq, condition); \
++} while (0)
++
++#define __swait_event_timeout(wq, condition, timeout) \
++ ___swait_event(wq, ___wait_cond_timeout(condition), \
++ TASK_UNINTERRUPTIBLE, timeout, \
++ __ret = schedule_timeout(__ret))
++
++#define swait_event_timeout(wq, condition, timeout) \
++({ \
++ long __ret = timeout; \
++ if (!___wait_cond_timeout(condition)) \
++ __ret = __swait_event_timeout(wq, condition, timeout); \
++ __ret; \
++})
++
++#define __swait_event_interruptible(wq, condition) \
++ ___swait_event(wq, condition, TASK_INTERRUPTIBLE, 0, \
++ schedule())
++
++#define swait_event_interruptible(wq, condition) \
++({ \
++ int __ret = 0; \
++ if (!(condition)) \
++ __ret = __swait_event_interruptible(wq, condition); \
++ __ret; \
++})
++
++#define __swait_event_interruptible_timeout(wq, condition, timeout) \
++ ___swait_event(wq, ___wait_cond_timeout(condition), \
++ TASK_INTERRUPTIBLE, timeout, \
++ __ret = schedule_timeout(__ret))
++
++#define swait_event_interruptible_timeout(wq, condition, timeout) \
++({ \
++ long __ret = timeout; \
++ if (!___wait_cond_timeout(condition)) \
++ __ret = __swait_event_interruptible_timeout(wq, \
++ condition, timeout); \
++ __ret; \
++})
++
++#endif /* _LINUX_SWAIT_H */
+--- a/kernel/sched/Makefile
++++ b/kernel/sched/Makefile
+@@ -13,7 +13,7 @@ endif
+
+ obj-y += core.o loadavg.o clock.o cputime.o
+ obj-y += idle_task.o fair.o rt.o deadline.o stop_task.o
+-obj-y += wait.o completion.o idle.o
++obj-y += wait.o swait.o completion.o idle.o
+ obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o
+ obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o
+ obj-$(CONFIG_SCHEDSTATS) += stats.o
+--- /dev/null
++++ b/kernel/sched/swait.c
+@@ -0,0 +1,123 @@
++#include <linux/sched.h>
++#include <linux/swait.h>
++
++void __init_swait_queue_head(struct swait_queue_head *q, const char *name,
++ struct lock_class_key *key)
++{
++ raw_spin_lock_init(&q->lock);
++ lockdep_set_class_and_name(&q->lock, key, name);
++ INIT_LIST_HEAD(&q->task_list);
++}
++EXPORT_SYMBOL(__init_swait_queue_head);
++
++/*
++ * The thing about the wake_up_state() return value; I think we can ignore it.
++ *
++ * If for some reason it would return 0, that means the previously waiting
++ * task is already running, so it will observe condition true (or has already).
++ */
++void swake_up_locked(struct swait_queue_head *q)
++{
++ struct swait_queue *curr;
++
++ if (list_empty(&q->task_list))
++ return;
++
++ curr = list_first_entry(&q->task_list, typeof(*curr), task_list);
++ wake_up_process(curr->task);
++ list_del_init(&curr->task_list);
++}
++EXPORT_SYMBOL(swake_up_locked);
++
++void swake_up(struct swait_queue_head *q)
++{
++ unsigned long flags;
++
++ if (!swait_active(q))
++ return;
++
++ raw_spin_lock_irqsave(&q->lock, flags);
++ swake_up_locked(q);
++ raw_spin_unlock_irqrestore(&q->lock, flags);
++}
++EXPORT_SYMBOL(swake_up);
++
++/*
++ * Does not allow usage from IRQ disabled, since we must be able to
++ * release IRQs to guarantee bounded hold time.
++ */
++void swake_up_all(struct swait_queue_head *q)
++{
++ struct swait_queue *curr;
++ LIST_HEAD(tmp);
++
++ if (!swait_active(q))
++ return;
++
++ raw_spin_lock_irq(&q->lock);
++ list_splice_init(&q->task_list, &tmp);
++ while (!list_empty(&tmp)) {
++ curr = list_first_entry(&tmp, typeof(*curr), task_list);
++
++ wake_up_state(curr->task, TASK_NORMAL);
++ list_del_init(&curr->task_list);
++
++ if (list_empty(&tmp))
++ break;
++
++ raw_spin_unlock_irq(&q->lock);
++ raw_spin_lock_irq(&q->lock);
++ }
++ raw_spin_unlock_irq(&q->lock);
++}
++EXPORT_SYMBOL(swake_up_all);
++
++void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait)
++{
++ wait->task = current;
++ if (list_empty(&wait->task_list))
++ list_add(&wait->task_list, &q->task_list);
++}
++
++void prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait, int state)
++{
++ unsigned long flags;
++
++ raw_spin_lock_irqsave(&q->lock, flags);
++ __prepare_to_swait(q, wait);
++ set_current_state(state);
++ raw_spin_unlock_irqrestore(&q->lock, flags);
++}
++EXPORT_SYMBOL(prepare_to_swait);
++
++long prepare_to_swait_event(struct swait_queue_head *q, struct swait_queue *wait, int state)
++{
++ if (signal_pending_state(state, current))
++ return -ERESTARTSYS;
++
++ prepare_to_swait(q, wait, state);
++
++ return 0;
++}
++EXPORT_SYMBOL(prepare_to_swait_event);
++
++void __finish_swait(struct swait_queue_head *q, struct swait_queue *wait)
++{
++ __set_current_state(TASK_RUNNING);
++ if (!list_empty(&wait->task_list))
++ list_del_init(&wait->task_list);
++}
++
++void finish_swait(struct swait_queue_head *q, struct swait_queue *wait)
++{
++ unsigned long flags;
++
++ __set_current_state(TASK_RUNNING);
++
++ if (!list_empty_careful(&wait->task_list)) {
++ raw_spin_lock_irqsave(&q->lock, flags);
++ list_del_init(&wait->task_list);
++ raw_spin_unlock_irqrestore(&q->lock, flags);
++ }
++}
++EXPORT_SYMBOL(finish_swait);
diff --git a/patches/0002-clk-at91-make-use-of-syscon-regmap-internally.patch b/patches/0002-clk-at91-make-use-of-syscon-regmap-internally.patch
new file mode 100644
index 00000000000000..ab73e058c4d1d8
--- /dev/null
+++ b/patches/0002-clk-at91-make-use-of-syscon-regmap-internally.patch
@@ -0,0 +1,3252 @@
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Sun, 7 Sep 2014 08:14:29 +0200
+Subject: [PATCH 02/13] clk: at91: make use of syscon/regmap internally
+
+Use the regmap coming from syscon to access the registers instead of using
+pmc_read/pmc_write. This allows to avoid passing the at91_pmc structure to
+the child nodes of the PMC.
+
+The final benefit is to have each clock register itself instead of having
+to iterate over the children.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Acked-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/clk/at91/clk-generated.c | 91 +++++++------
+ drivers/clk/at91/clk-h32mx.c | 32 ++--
+ drivers/clk/at91/clk-main.c | 248 +++++++++++++++++++++++-------------
+ drivers/clk/at91/clk-master.c | 68 ++++++---
+ drivers/clk/at91/clk-peripheral.c | 134 +++++++++++--------
+ drivers/clk/at91/clk-pll.c | 119 ++++++++++-------
+ drivers/clk/at91/clk-plldiv.c | 42 ++----
+ drivers/clk/at91/clk-programmable.c | 92 +++++++------
+ drivers/clk/at91/clk-slow.c | 26 ++-
+ drivers/clk/at91/clk-smd.c | 54 ++++---
+ drivers/clk/at91/clk-system.c | 60 +++++---
+ drivers/clk/at91/clk-usb.c | 121 +++++++++--------
+ drivers/clk/at91/clk-utmi.c | 53 ++++---
+ drivers/clk/at91/pmc.c | 155 +---------------------
+ drivers/clk/at91/pmc.h | 89 ------------
+ 15 files changed, 691 insertions(+), 693 deletions(-)
+
+--- a/drivers/clk/at91/clk-generated.c
++++ b/drivers/clk/at91/clk-generated.c
+@@ -17,6 +17,8 @@
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/io.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include "pmc.h"
+
+@@ -28,8 +30,9 @@
+
+ struct clk_generated {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ struct clk_range range;
++ spinlock_t *lock;
+ u32 id;
+ u32 gckdiv;
+ u8 parent_id;
+@@ -41,49 +44,52 @@ struct clk_generated {
+ static int clk_generated_enable(struct clk_hw *hw)
+ {
+ struct clk_generated *gck = to_clk_generated(hw);
+- struct at91_pmc *pmc = gck->pmc;
+- u32 tmp;
++ unsigned long flags;
+
+ pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n",
+ __func__, gck->gckdiv, gck->parent_id);
+
+- pmc_lock(pmc);
+- pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+- tmp = pmc_read(pmc, AT91_PMC_PCR) &
+- ~(AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK);
+- pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_GCKCSS(gck->parent_id)
+- | AT91_PMC_PCR_CMD
+- | AT91_PMC_PCR_GCKDIV(gck->gckdiv)
+- | AT91_PMC_PCR_GCKEN);
+- pmc_unlock(pmc);
++ spin_lock_irqsave(gck->lock, flags);
++ regmap_write(gck->regmap, AT91_PMC_PCR,
++ (gck->id & AT91_PMC_PCR_PID_MASK));
++ regmap_update_bits(gck->regmap, AT91_PMC_PCR,
++ AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK |
++ AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN,
++ AT91_PMC_PCR_GCKCSS(gck->parent_id) |
++ AT91_PMC_PCR_CMD |
++ AT91_PMC_PCR_GCKDIV(gck->gckdiv) |
++ AT91_PMC_PCR_GCKEN);
++ spin_unlock_irqrestore(gck->lock, flags);
+ return 0;
+ }
+
+ static void clk_generated_disable(struct clk_hw *hw)
+ {
+ struct clk_generated *gck = to_clk_generated(hw);
+- struct at91_pmc *pmc = gck->pmc;
+- u32 tmp;
++ unsigned long flags;
+
+- pmc_lock(pmc);
+- pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+- tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_GCKEN;
+- pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD);
+- pmc_unlock(pmc);
++ spin_lock_irqsave(gck->lock, flags);
++ regmap_write(gck->regmap, AT91_PMC_PCR,
++ (gck->id & AT91_PMC_PCR_PID_MASK));
++ regmap_update_bits(gck->regmap, AT91_PMC_PCR,
++ AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN,
++ AT91_PMC_PCR_CMD);
++ spin_unlock_irqrestore(gck->lock, flags);
+ }
+
+ static int clk_generated_is_enabled(struct clk_hw *hw)
+ {
+ struct clk_generated *gck = to_clk_generated(hw);
+- struct at91_pmc *pmc = gck->pmc;
+- int ret;
++ unsigned long flags;
++ unsigned int status;
+
+- pmc_lock(pmc);
+- pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+- ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_GCKEN);
+- pmc_unlock(pmc);
++ spin_lock_irqsave(gck->lock, flags);
++ regmap_write(gck->regmap, AT91_PMC_PCR,
++ (gck->id & AT91_PMC_PCR_PID_MASK));
++ regmap_read(gck->regmap, AT91_PMC_PCR, &status);
++ spin_unlock_irqrestore(gck->lock, flags);
+
+- return ret;
++ return status & AT91_PMC_PCR_GCKEN ? 1 : 0;
+ }
+
+ static unsigned long
+@@ -214,13 +220,14 @@ static const struct clk_ops generated_op
+ */
+ static void clk_generated_startup(struct clk_generated *gck)
+ {
+- struct at91_pmc *pmc = gck->pmc;
+ u32 tmp;
++ unsigned long flags;
+
+- pmc_lock(pmc);
+- pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+- tmp = pmc_read(pmc, AT91_PMC_PCR);
+- pmc_unlock(pmc);
++ spin_lock_irqsave(gck->lock, flags);
++ regmap_write(gck->regmap, AT91_PMC_PCR,
++ (gck->id & AT91_PMC_PCR_PID_MASK));
++ regmap_read(gck->regmap, AT91_PMC_PCR, &tmp);
++ spin_unlock_irqrestore(gck->lock, flags);
+
+ gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK)
+ >> AT91_PMC_PCR_GCKCSS_OFFSET;
+@@ -229,8 +236,8 @@ static void clk_generated_startup(struct
+ }
+
+ static struct clk * __init
+-at91_clk_register_generated(struct at91_pmc *pmc, const char *name,
+- const char **parent_names, u8 num_parents,
++at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const char
++ *name, const char **parent_names, u8 num_parents,
+ u8 id, const struct clk_range *range)
+ {
+ struct clk_generated *gck;
+@@ -249,7 +256,8 @@ at91_clk_register_generated(struct at91_
+
+ gck->id = id;
+ gck->hw.init = &init;
+- gck->pmc = pmc;
++ gck->regmap = regmap;
++ gck->lock = lock;
+ gck->range = *range;
+
+ clk = clk_register(NULL, &gck->hw);
+@@ -261,8 +269,7 @@ at91_clk_register_generated(struct at91_
+ return clk;
+ }
+
+-void __init of_sama5d2_clk_generated_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++void __init of_sama5d2_clk_generated_setup(struct device_node *np)
+ {
+ int num;
+ u32 id;
+@@ -272,6 +279,7 @@ void __init of_sama5d2_clk_generated_set
+ const char *parent_names[GENERATED_SOURCE_MAX];
+ struct device_node *gcknp;
+ struct clk_range range = CLK_RANGE(0, 0);
++ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX)
+@@ -283,6 +291,10 @@ void __init of_sama5d2_clk_generated_set
+ if (!num || num > PERIPHERAL_MAX)
+ return;
+
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
+ for_each_child_of_node(np, gcknp) {
+ if (of_property_read_u32(gcknp, "reg", &id))
+ continue;
+@@ -296,11 +308,14 @@ void __init of_sama5d2_clk_generated_set
+ of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
+ &range);
+
+- clk = at91_clk_register_generated(pmc, name, parent_names,
+- num_parents, id, &range);
++ clk = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
++ parent_names, num_parents,
++ id, &range);
+ if (IS_ERR(clk))
+ continue;
+
+ of_clk_add_provider(gcknp, of_clk_src_simple_get, clk);
+ }
+ }
++CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
++ of_sama5d2_clk_generated_setup);
+--- a/drivers/clk/at91/clk-h32mx.c
++++ b/drivers/clk/at91/clk-h32mx.c
+@@ -24,6 +24,8 @@
+ #include <linux/irq.h>
+ #include <linux/sched.h>
+ #include <linux/wait.h>
++#include <linux/regmap.h>
++#include <linux/mfd/syscon.h>
+
+ #include "pmc.h"
+
+@@ -31,7 +33,7 @@
+
+ struct clk_sama5d4_h32mx {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ };
+
+ #define to_clk_sama5d4_h32mx(hw) container_of(hw, struct clk_sama5d4_h32mx, hw)
+@@ -40,8 +42,10 @@ static unsigned long clk_sama5d4_h32mx_r
+ unsigned long parent_rate)
+ {
+ struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
++ unsigned int mckr;
+
+- if (pmc_read(h32mxclk->pmc, AT91_PMC_MCKR) & AT91_PMC_H32MXDIV)
++ regmap_read(h32mxclk->regmap, AT91_PMC_MCKR, &mckr);
++ if (mckr & AT91_PMC_H32MXDIV)
+ return parent_rate / 2;
+
+ if (parent_rate > H32MX_MAX_FREQ)
+@@ -70,18 +74,16 @@ static int clk_sama5d4_h32mx_set_rate(st
+ unsigned long parent_rate)
+ {
+ struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
+- struct at91_pmc *pmc = h32mxclk->pmc;
+- u32 tmp;
++ u32 mckr = 0;
+
+ if (parent_rate != rate && (parent_rate / 2) != rate)
+ return -EINVAL;
+
+- pmc_lock(pmc);
+- tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_H32MXDIV;
+ if ((parent_rate / 2) == rate)
+- tmp |= AT91_PMC_H32MXDIV;
+- pmc_write(pmc, AT91_PMC_MCKR, tmp);
+- pmc_unlock(pmc);
++ mckr = AT91_PMC_H32MXDIV;
++
++ regmap_update_bits(h32mxclk->regmap, AT91_PMC_MCKR,
++ AT91_PMC_H32MXDIV, mckr);
+
+ return 0;
+ }
+@@ -92,14 +94,18 @@ static const struct clk_ops h32mx_ops =
+ .set_rate = clk_sama5d4_h32mx_set_rate,
+ };
+
+-void __init of_sama5d4_clk_h32mx_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
+ {
+ struct clk_sama5d4_h32mx *h32mxclk;
+ struct clk_init_data init;
+ const char *parent_name;
++ struct regmap *regmap;
+ struct clk *clk;
+
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
+ h32mxclk = kzalloc(sizeof(*h32mxclk), GFP_KERNEL);
+ if (!h32mxclk)
+ return;
+@@ -113,7 +119,7 @@ void __init of_sama5d4_clk_h32mx_setup(s
+ init.flags = CLK_SET_RATE_GATE;
+
+ h32mxclk->hw.init = &init;
+- h32mxclk->pmc = pmc;
++ h32mxclk->regmap = regmap;
+
+ clk = clk_register(NULL, &h32mxclk->hw);
+ if (!clk) {
+@@ -123,3 +129,5 @@ void __init of_sama5d4_clk_h32mx_setup(s
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ }
++CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
++ of_sama5d4_clk_h32mx_setup);
+--- a/drivers/clk/at91/clk-main.c
++++ b/drivers/clk/at91/clk-main.c
+@@ -18,6 +18,8 @@
+ #include <linux/io.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+ #include <linux/sched.h>
+ #include <linux/wait.h>
+
+@@ -34,7 +36,7 @@
+
+ struct clk_main_osc {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ };
+@@ -43,7 +45,7 @@ struct clk_main_osc {
+
+ struct clk_main_rc_osc {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ unsigned long frequency;
+@@ -54,14 +56,14 @@ struct clk_main_rc_osc {
+
+ struct clk_rm9200_main {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ };
+
+ #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
+
+ struct clk_sam9x5_main {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ u8 parent;
+@@ -79,25 +81,36 @@ static irqreturn_t clk_main_osc_irq_hand
+ return IRQ_HANDLED;
+ }
+
++static inline bool clk_main_osc_ready(struct regmap *regmap)
++{
++ unsigned int status;
++
++ regmap_read(regmap, AT91_PMC_SR, &status);
++
++ return status & AT91_PMC_MOSCS;
++}
++
+ static int clk_main_osc_prepare(struct clk_hw *hw)
+ {
+ struct clk_main_osc *osc = to_clk_main_osc(hw);
+- struct at91_pmc *pmc = osc->pmc;
++ struct regmap *regmap = osc->regmap;
+ u32 tmp;
+
+- tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;
++ regmap_read(regmap, AT91_CKGR_MOR, &tmp);
++ tmp &= ~MOR_KEY_MASK;
++
+ if (tmp & AT91_PMC_OSCBYPASS)
+ return 0;
+
+ if (!(tmp & AT91_PMC_MOSCEN)) {
+ tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
+- pmc_write(pmc, AT91_CKGR_MOR, tmp);
++ regmap_write(regmap, AT91_CKGR_MOR, tmp);
+ }
+
+- while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS)) {
++ while (!clk_main_osc_ready(regmap)) {
+ enable_irq(osc->irq);
+ wait_event(osc->wait,
+- pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS);
++ clk_main_osc_ready(regmap));
+ }
+
+ return 0;
+@@ -106,9 +119,10 @@ static int clk_main_osc_prepare(struct c
+ static void clk_main_osc_unprepare(struct clk_hw *hw)
+ {
+ struct clk_main_osc *osc = to_clk_main_osc(hw);
+- struct at91_pmc *pmc = osc->pmc;
+- u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);
++ struct regmap *regmap = osc->regmap;
++ u32 tmp;
+
++ regmap_read(regmap, AT91_CKGR_MOR, &tmp);
+ if (tmp & AT91_PMC_OSCBYPASS)
+ return;
+
+@@ -116,20 +130,22 @@ static void clk_main_osc_unprepare(struc
+ return;
+
+ tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
+- pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
++ regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
+ }
+
+ static int clk_main_osc_is_prepared(struct clk_hw *hw)
+ {
+ struct clk_main_osc *osc = to_clk_main_osc(hw);
+- struct at91_pmc *pmc = osc->pmc;
+- u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);
++ struct regmap *regmap = osc->regmap;
++ u32 tmp, status;
+
++ regmap_read(regmap, AT91_CKGR_MOR, &tmp);
+ if (tmp & AT91_PMC_OSCBYPASS)
+ return 1;
+
+- return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS) &&
+- (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN));
++ regmap_read(regmap, AT91_PMC_SR, &status);
++
++ return (status & AT91_PMC_MOSCS) && (tmp & AT91_PMC_MOSCEN);
+ }
+
+ static const struct clk_ops main_osc_ops = {
+@@ -139,7 +155,7 @@ static const struct clk_ops main_osc_ops
+ };
+
+ static struct clk * __init
+-at91_clk_register_main_osc(struct at91_pmc *pmc,
++at91_clk_register_main_osc(struct regmap *regmap,
+ unsigned int irq,
+ const char *name,
+ const char *parent_name,
+@@ -150,7 +166,7 @@ at91_clk_register_main_osc(struct at91_p
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+- if (!pmc || !irq || !name || !parent_name)
++ if (!irq || !name || !parent_name)
+ return ERR_PTR(-EINVAL);
+
+ osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+@@ -164,7 +180,7 @@ at91_clk_register_main_osc(struct at91_p
+ init.flags = CLK_IGNORE_UNUSED;
+
+ osc->hw.init = &init;
+- osc->pmc = pmc;
++ osc->regmap = regmap;
+ osc->irq = irq;
+
+ init_waitqueue_head(&osc->wait);
+@@ -177,10 +193,10 @@ at91_clk_register_main_osc(struct at91_p
+ }
+
+ if (bypass)
+- pmc_write(pmc, AT91_CKGR_MOR,
+- (pmc_read(pmc, AT91_CKGR_MOR) &
+- ~(MOR_KEY_MASK | AT91_PMC_MOSCEN)) |
+- AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
++ regmap_update_bits(regmap,
++ AT91_CKGR_MOR, MOR_KEY_MASK |
++ AT91_PMC_MOSCEN,
++ AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
+
+ clk = clk_register(NULL, &osc->hw);
+ if (IS_ERR(clk)) {
+@@ -191,29 +207,35 @@ at91_clk_register_main_osc(struct at91_p
+ return clk;
+ }
+
+-void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
+ {
+ struct clk *clk;
+ unsigned int irq;
+ const char *name = np->name;
+ const char *parent_name;
++ struct regmap *regmap;
+ bool bypass;
+
+ of_property_read_string(np, "clock-output-names", &name);
+ bypass = of_property_read_bool(np, "atmel,osc-bypass");
+ parent_name = of_clk_get_parent_name(np, 0);
+
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq)
+ return;
+
+- clk = at91_clk_register_main_osc(pmc, irq, name, parent_name, bypass);
++ clk = at91_clk_register_main_osc(regmap, irq, name, parent_name, bypass);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ }
++CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
++ of_at91rm9200_clk_main_osc_setup);
+
+ static irqreturn_t clk_main_rc_osc_irq_handler(int irq, void *dev_id)
+ {
+@@ -225,23 +247,32 @@ static irqreturn_t clk_main_rc_osc_irq_h
+ return IRQ_HANDLED;
+ }
+
++static bool clk_main_rc_osc_ready(struct regmap *regmap)
++{
++ unsigned int status;
++
++ regmap_read(regmap, AT91_PMC_SR, &status);
++
++ return status & AT91_PMC_MOSCRCS;
++}
++
+ static int clk_main_rc_osc_prepare(struct clk_hw *hw)
+ {
+ struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
+- struct at91_pmc *pmc = osc->pmc;
+- u32 tmp;
++ struct regmap *regmap = osc->regmap;
++ unsigned int mor;
+
+- tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;
++ regmap_read(regmap, AT91_CKGR_MOR, &mor);
+
+- if (!(tmp & AT91_PMC_MOSCRCEN)) {
+- tmp |= AT91_PMC_MOSCRCEN | AT91_PMC_KEY;
+- pmc_write(pmc, AT91_CKGR_MOR, tmp);
+- }
++ if (!(mor & AT91_PMC_MOSCRCEN))
++ regmap_update_bits(regmap, AT91_CKGR_MOR,
++ MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
++ AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
+
+- while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS)) {
++ while (!clk_main_rc_osc_ready(regmap)) {
+ enable_irq(osc->irq);
+ wait_event(osc->wait,
+- pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS);
++ clk_main_rc_osc_ready(regmap));
+ }
+
+ return 0;
+@@ -250,23 +281,28 @@ static int clk_main_rc_osc_prepare(struc
+ static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
+ {
+ struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
+- struct at91_pmc *pmc = osc->pmc;
+- u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);
++ struct regmap *regmap = osc->regmap;
++ unsigned int mor;
+
+- if (!(tmp & AT91_PMC_MOSCRCEN))
++ regmap_read(regmap, AT91_CKGR_MOR, &mor);
++
++ if (!(mor & AT91_PMC_MOSCRCEN))
+ return;
+
+- tmp &= ~(MOR_KEY_MASK | AT91_PMC_MOSCRCEN);
+- pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
++ regmap_update_bits(regmap, AT91_CKGR_MOR,
++ MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY);
+ }
+
+ static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
+ {
+ struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
+- struct at91_pmc *pmc = osc->pmc;
++ struct regmap *regmap = osc->regmap;
++ unsigned int mor, status;
++
++ regmap_read(regmap, AT91_CKGR_MOR, &mor);
++ regmap_read(regmap, AT91_PMC_SR, &status);
+
+- return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS) &&
+- (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCRCEN));
++ return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS);
+ }
+
+ static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
+@@ -294,7 +330,7 @@ static const struct clk_ops main_rc_osc_
+ };
+
+ static struct clk * __init
+-at91_clk_register_main_rc_osc(struct at91_pmc *pmc,
++at91_clk_register_main_rc_osc(struct regmap *regmap,
+ unsigned int irq,
+ const char *name,
+ u32 frequency, u32 accuracy)
+@@ -304,7 +340,7 @@ at91_clk_register_main_rc_osc(struct at9
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+- if (!pmc || !irq || !name || !frequency)
++ if (!name || !frequency)
+ return ERR_PTR(-EINVAL);
+
+ osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+@@ -318,7 +354,7 @@ at91_clk_register_main_rc_osc(struct at9
+ init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED;
+
+ osc->hw.init = &init;
+- osc->pmc = pmc;
++ osc->regmap = regmap;
+ osc->irq = irq;
+ osc->frequency = frequency;
+ osc->accuracy = accuracy;
+@@ -339,14 +375,14 @@ at91_clk_register_main_rc_osc(struct at9
+ return clk;
+ }
+
+-void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
+ {
+ struct clk *clk;
+ unsigned int irq;
+ u32 frequency = 0;
+ u32 accuracy = 0;
+ const char *name = np->name;
++ struct regmap *regmap;
+
+ of_property_read_string(np, "clock-output-names", &name);
+ of_property_read_u32(np, "clock-frequency", &frequency);
+@@ -356,25 +392,31 @@ void __init of_at91sam9x5_clk_main_rc_os
+ if (!irq)
+ return;
+
+- clk = at91_clk_register_main_rc_osc(pmc, irq, name, frequency,
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
++ clk = at91_clk_register_main_rc_osc(regmap, irq, name, frequency,
+ accuracy);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ }
++CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
++ of_at91sam9x5_clk_main_rc_osc_setup);
+
+
+-static int clk_main_probe_frequency(struct at91_pmc *pmc)
++static int clk_main_probe_frequency(struct regmap *regmap)
+ {
+ unsigned long prep_time, timeout;
+- u32 tmp;
++ unsigned int mcfr;
+
+ timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
+ do {
+ prep_time = jiffies;
+- tmp = pmc_read(pmc, AT91_CKGR_MCFR);
+- if (tmp & AT91_PMC_MAINRDY)
++ regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
++ if (mcfr & AT91_PMC_MAINRDY)
+ return 0;
+ usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
+ } while (time_before(prep_time, timeout));
+@@ -382,34 +424,37 @@ static int clk_main_probe_frequency(stru
+ return -ETIMEDOUT;
+ }
+
+-static unsigned long clk_main_recalc_rate(struct at91_pmc *pmc,
++static unsigned long clk_main_recalc_rate(struct regmap *regmap,
+ unsigned long parent_rate)
+ {
+- u32 tmp;
++ unsigned int mcfr;
+
+ if (parent_rate)
+ return parent_rate;
+
+ pr_warn("Main crystal frequency not set, using approximate value\n");
+- tmp = pmc_read(pmc, AT91_CKGR_MCFR);
+- if (!(tmp & AT91_PMC_MAINRDY))
++ regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
++ if (!(mcfr & AT91_PMC_MAINRDY))
+ return 0;
+
+- return ((tmp & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
++ return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
+ }
+
+ static int clk_rm9200_main_prepare(struct clk_hw *hw)
+ {
+ struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
+
+- return clk_main_probe_frequency(clkmain->pmc);
++ return clk_main_probe_frequency(clkmain->regmap);
+ }
+
+ static int clk_rm9200_main_is_prepared(struct clk_hw *hw)
+ {
+ struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
++ unsigned int status;
++
++ regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status);
+
+- return !!(pmc_read(clkmain->pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINRDY);
++ return status & AT91_PMC_MAINRDY ? 1 : 0;
+ }
+
+ static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
+@@ -417,7 +462,7 @@ static unsigned long clk_rm9200_main_rec
+ {
+ struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
+
+- return clk_main_recalc_rate(clkmain->pmc, parent_rate);
++ return clk_main_recalc_rate(clkmain->regmap, parent_rate);
+ }
+
+ static const struct clk_ops rm9200_main_ops = {
+@@ -427,7 +472,7 @@ static const struct clk_ops rm9200_main_
+ };
+
+ static struct clk * __init
+-at91_clk_register_rm9200_main(struct at91_pmc *pmc,
++at91_clk_register_rm9200_main(struct regmap *regmap,
+ const char *name,
+ const char *parent_name)
+ {
+@@ -435,7 +480,7 @@ at91_clk_register_rm9200_main(struct at9
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+- if (!pmc || !name)
++ if (!name)
+ return ERR_PTR(-EINVAL);
+
+ if (!parent_name)
+@@ -452,7 +497,7 @@ at91_clk_register_rm9200_main(struct at9
+ init.flags = 0;
+
+ clkmain->hw.init = &init;
+- clkmain->pmc = pmc;
++ clkmain->regmap = regmap;
+
+ clk = clk_register(NULL, &clkmain->hw);
+ if (IS_ERR(clk))
+@@ -461,22 +506,28 @@ at91_clk_register_rm9200_main(struct at9
+ return clk;
+ }
+
+-void __init of_at91rm9200_clk_main_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
+ {
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
++ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ of_property_read_string(np, "clock-output-names", &name);
+
+- clk = at91_clk_register_rm9200_main(pmc, name, parent_name);
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
++ clk = at91_clk_register_rm9200_main(regmap, name, parent_name);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ }
++CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
++ of_at91rm9200_clk_main_setup);
+
+ static irqreturn_t clk_sam9x5_main_irq_handler(int irq, void *dev_id)
+ {
+@@ -488,25 +539,34 @@ static irqreturn_t clk_sam9x5_main_irq_h
+ return IRQ_HANDLED;
+ }
+
++static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
++{
++ unsigned int status;
++
++ regmap_read(regmap, AT91_PMC_SR, &status);
++
++ return status & AT91_PMC_MOSCSELS ? 1 : 0;
++}
++
+ static int clk_sam9x5_main_prepare(struct clk_hw *hw)
+ {
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
+- struct at91_pmc *pmc = clkmain->pmc;
++ struct regmap *regmap = clkmain->regmap;
+
+- while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) {
++ while (!clk_sam9x5_main_ready(regmap)) {
+ enable_irq(clkmain->irq);
+ wait_event(clkmain->wait,
+- pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS);
++ clk_sam9x5_main_ready(regmap));
+ }
+
+- return clk_main_probe_frequency(pmc);
++ return clk_main_probe_frequency(regmap);
+ }
+
+ static int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
+ {
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
+
+- return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS);
++ return clk_sam9x5_main_ready(clkmain->regmap);
+ }
+
+ static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
+@@ -514,29 +574,30 @@ static unsigned long clk_sam9x5_main_rec
+ {
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
+
+- return clk_main_recalc_rate(clkmain->pmc, parent_rate);
++ return clk_main_recalc_rate(clkmain->regmap, parent_rate);
+ }
+
+ static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
+ {
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
+- struct at91_pmc *pmc = clkmain->pmc;
+- u32 tmp;
++ struct regmap *regmap = clkmain->regmap;
++ unsigned int tmp;
+
+ if (index > 1)
+ return -EINVAL;
+
+- tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;
++ regmap_read(regmap, AT91_CKGR_MOR, &tmp);
++ tmp &= ~MOR_KEY_MASK;
+
+ if (index && !(tmp & AT91_PMC_MOSCSEL))
+- pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
++ regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
+ else if (!index && (tmp & AT91_PMC_MOSCSEL))
+- pmc_write(pmc, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
++ regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
+
+- while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) {
++ while (!clk_sam9x5_main_ready(regmap)) {
+ enable_irq(clkmain->irq);
+ wait_event(clkmain->wait,
+- pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS);
++ clk_sam9x5_main_ready(regmap));
+ }
+
+ return 0;
+@@ -545,8 +606,11 @@ static int clk_sam9x5_main_set_parent(st
+ static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
+ {
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
++ unsigned int status;
+
+- return !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN);
++ regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
++
++ return status & AT91_PMC_MOSCEN ? 1 : 0;
+ }
+
+ static const struct clk_ops sam9x5_main_ops = {
+@@ -558,7 +622,7 @@ static const struct clk_ops sam9x5_main_
+ };
+
+ static struct clk * __init
+-at91_clk_register_sam9x5_main(struct at91_pmc *pmc,
++at91_clk_register_sam9x5_main(struct regmap *regmap,
+ unsigned int irq,
+ const char *name,
+ const char **parent_names,
+@@ -568,8 +632,9 @@ at91_clk_register_sam9x5_main(struct at9
+ struct clk_sam9x5_main *clkmain;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
++ unsigned int status;
+
+- if (!pmc || !irq || !name)
++ if (!name)
+ return ERR_PTR(-EINVAL);
+
+ if (!parent_names || !num_parents)
+@@ -586,10 +651,10 @@ at91_clk_register_sam9x5_main(struct at9
+ init.flags = CLK_SET_PARENT_GATE;
+
+ clkmain->hw.init = &init;
+- clkmain->pmc = pmc;
++ clkmain->regmap = regmap;
+ clkmain->irq = irq;
+- clkmain->parent = !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) &
+- AT91_PMC_MOSCEN);
++ regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
++ clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0;
+ init_waitqueue_head(&clkmain->wait);
+ irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN);
+ ret = request_irq(clkmain->irq, clk_sam9x5_main_irq_handler,
+@@ -606,20 +671,23 @@ at91_clk_register_sam9x5_main(struct at9
+ return clk;
+ }
+
+-void __init of_at91sam9x5_clk_main_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
+ {
+ struct clk *clk;
+ const char *parent_names[2];
+ int num_parents;
+ unsigned int irq;
+ const char *name = np->name;
++ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents <= 0 || num_parents > 2)
+ return;
+
+ of_clk_parent_fill(np, parent_names, num_parents);
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+@@ -627,10 +695,12 @@ void __init of_at91sam9x5_clk_main_setup
+ if (!irq)
+ return;
+
+- clk = at91_clk_register_sam9x5_main(pmc, irq, name, parent_names,
++ clk = at91_clk_register_sam9x5_main(regmap, irq, name, parent_names,
+ num_parents);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ }
++CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
++ of_at91sam9x5_clk_main_setup);
+--- a/drivers/clk/at91/clk-master.c
++++ b/drivers/clk/at91/clk-master.c
+@@ -19,6 +19,8 @@
+ #include <linux/sched.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include "pmc.h"
+
+@@ -44,7 +46,7 @@ struct clk_master_layout {
+
+ struct clk_master {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ const struct clk_master_layout *layout;
+@@ -60,15 +62,24 @@ static irqreturn_t clk_master_irq_handle
+
+ return IRQ_HANDLED;
+ }
++
++static inline bool clk_master_ready(struct regmap *regmap)
++{
++ unsigned int status;
++
++ regmap_read(regmap, AT91_PMC_SR, &status);
++
++ return status & AT91_PMC_MCKRDY ? 1 : 0;
++}
++
+ static int clk_master_prepare(struct clk_hw *hw)
+ {
+ struct clk_master *master = to_clk_master(hw);
+- struct at91_pmc *pmc = master->pmc;
+
+- while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY)) {
++ while (!clk_master_ready(master->regmap)) {
+ enable_irq(master->irq);
+ wait_event(master->wait,
+- pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY);
++ clk_master_ready(master->regmap));
+ }
+
+ return 0;
+@@ -78,7 +89,7 @@ static int clk_master_is_prepared(struct
+ {
+ struct clk_master *master = to_clk_master(hw);
+
+- return !!(pmc_read(master->pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY);
++ return clk_master_ready(master->regmap);
+ }
+
+ static unsigned long clk_master_recalc_rate(struct clk_hw *hw,
+@@ -88,18 +99,16 @@ static unsigned long clk_master_recalc_r
+ u8 div;
+ unsigned long rate = parent_rate;
+ struct clk_master *master = to_clk_master(hw);
+- struct at91_pmc *pmc = master->pmc;
+ const struct clk_master_layout *layout = master->layout;
+ const struct clk_master_characteristics *characteristics =
+ master->characteristics;
+- u32 tmp;
++ unsigned int mckr;
+
+- pmc_lock(pmc);
+- tmp = pmc_read(pmc, AT91_PMC_MCKR) & layout->mask;
+- pmc_unlock(pmc);
++ regmap_read(master->regmap, AT91_PMC_MCKR, &mckr);
++ mckr &= layout->mask;
+
+- pres = (tmp >> layout->pres_shift) & MASTER_PRES_MASK;
+- div = (tmp >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK;
++ pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK;
++ div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK;
+
+ if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX)
+ rate /= 3;
+@@ -119,9 +128,11 @@ static unsigned long clk_master_recalc_r
+ static u8 clk_master_get_parent(struct clk_hw *hw)
+ {
+ struct clk_master *master = to_clk_master(hw);
+- struct at91_pmc *pmc = master->pmc;
++ unsigned int mckr;
++
++ regmap_read(master->regmap, AT91_PMC_MCKR, &mckr);
+
+- return pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_CSS;
++ return mckr & AT91_PMC_CSS;
+ }
+
+ static const struct clk_ops master_ops = {
+@@ -132,7 +143,7 @@ static const struct clk_ops master_ops =
+ };
+
+ static struct clk * __init
+-at91_clk_register_master(struct at91_pmc *pmc, unsigned int irq,
++at91_clk_register_master(struct regmap *regmap, unsigned int irq,
+ const char *name, int num_parents,
+ const char **parent_names,
+ const struct clk_master_layout *layout,
+@@ -143,7 +154,7 @@ at91_clk_register_master(struct at91_pmc
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+- if (!pmc || !irq || !name || !num_parents || !parent_names)
++ if (!name || !num_parents || !parent_names)
+ return ERR_PTR(-EINVAL);
+
+ master = kzalloc(sizeof(*master), GFP_KERNEL);
+@@ -159,7 +170,7 @@ at91_clk_register_master(struct at91_pmc
+ master->hw.init = &init;
+ master->layout = layout;
+ master->characteristics = characteristics;
+- master->pmc = pmc;
++ master->regmap = regmap;
+ master->irq = irq;
+ init_waitqueue_head(&master->wait);
+ irq_set_status_flags(master->irq, IRQ_NOAUTOEN);
+@@ -217,7 +228,7 @@ of_at91_clk_master_get_characteristics(s
+ }
+
+ static void __init
+-of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc,
++of_at91_clk_master_setup(struct device_node *np,
+ const struct clk_master_layout *layout)
+ {
+ struct clk *clk;
+@@ -226,6 +237,7 @@ of_at91_clk_master_setup(struct device_n
+ const char *parent_names[MASTER_SOURCE_MAX];
+ const char *name = np->name;
+ struct clk_master_characteristics *characteristics;
++ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX)
+@@ -239,11 +251,15 @@ of_at91_clk_master_setup(struct device_n
+ if (!characteristics)
+ return;
+
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq)
+ goto out_free_characteristics;
+
+- clk = at91_clk_register_master(pmc, irq, name, num_parents,
++ clk = at91_clk_register_master(regmap, irq, name, num_parents,
+ parent_names, layout,
+ characteristics);
+ if (IS_ERR(clk))
+@@ -256,14 +272,16 @@ of_at91_clk_master_setup(struct device_n
+ kfree(characteristics);
+ }
+
+-void __init of_at91rm9200_clk_master_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
+ {
+- of_at91_clk_master_setup(np, pmc, &at91rm9200_master_layout);
++ of_at91_clk_master_setup(np, &at91rm9200_master_layout);
+ }
++CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
++ of_at91rm9200_clk_master_setup);
+
+-void __init of_at91sam9x5_clk_master_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
+ {
+- of_at91_clk_master_setup(np, pmc, &at91sam9x5_master_layout);
++ of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
+ }
++CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
++ of_at91sam9x5_clk_master_setup);
+--- a/drivers/clk/at91/clk-peripheral.c
++++ b/drivers/clk/at91/clk-peripheral.c
+@@ -14,9 +14,13 @@
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/io.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include "pmc.h"
+
++DEFINE_SPINLOCK(pmc_pcr_lock);
++
+ #define PERIPHERAL_MAX 64
+
+ #define PERIPHERAL_AT91RM9200 0
+@@ -33,7 +37,7 @@
+
+ struct clk_peripheral {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ u32 id;
+ };
+
+@@ -41,8 +45,9 @@ struct clk_peripheral {
+
+ struct clk_sam9x5_peripheral {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ struct clk_range range;
++ spinlock_t *lock;
+ u32 id;
+ u32 div;
+ bool auto_div;
+@@ -54,7 +59,6 @@ struct clk_sam9x5_peripheral {
+ static int clk_peripheral_enable(struct clk_hw *hw)
+ {
+ struct clk_peripheral *periph = to_clk_peripheral(hw);
+- struct at91_pmc *pmc = periph->pmc;
+ int offset = AT91_PMC_PCER;
+ u32 id = periph->id;
+
+@@ -62,14 +66,14 @@ static int clk_peripheral_enable(struct
+ return 0;
+ if (id > PERIPHERAL_ID_MAX)
+ offset = AT91_PMC_PCER1;
+- pmc_write(pmc, offset, PERIPHERAL_MASK(id));
++ regmap_write(periph->regmap, offset, PERIPHERAL_MASK(id));
++
+ return 0;
+ }
+
+ static void clk_peripheral_disable(struct clk_hw *hw)
+ {
+ struct clk_peripheral *periph = to_clk_peripheral(hw);
+- struct at91_pmc *pmc = periph->pmc;
+ int offset = AT91_PMC_PCDR;
+ u32 id = periph->id;
+
+@@ -77,21 +81,23 @@ static void clk_peripheral_disable(struc
+ return;
+ if (id > PERIPHERAL_ID_MAX)
+ offset = AT91_PMC_PCDR1;
+- pmc_write(pmc, offset, PERIPHERAL_MASK(id));
++ regmap_write(periph->regmap, offset, PERIPHERAL_MASK(id));
+ }
+
+ static int clk_peripheral_is_enabled(struct clk_hw *hw)
+ {
+ struct clk_peripheral *periph = to_clk_peripheral(hw);
+- struct at91_pmc *pmc = periph->pmc;
+ int offset = AT91_PMC_PCSR;
++ unsigned int status;
+ u32 id = periph->id;
+
+ if (id < PERIPHERAL_ID_MIN)
+ return 1;
+ if (id > PERIPHERAL_ID_MAX)
+ offset = AT91_PMC_PCSR1;
+- return !!(pmc_read(pmc, offset) & PERIPHERAL_MASK(id));
++ regmap_read(periph->regmap, offset, &status);
++
++ return status & PERIPHERAL_MASK(id) ? 1 : 0;
+ }
+
+ static const struct clk_ops peripheral_ops = {
+@@ -101,14 +107,14 @@ static const struct clk_ops peripheral_o
+ };
+
+ static struct clk * __init
+-at91_clk_register_peripheral(struct at91_pmc *pmc, const char *name,
++at91_clk_register_peripheral(struct regmap *regmap, const char *name,
+ const char *parent_name, u32 id)
+ {
+ struct clk_peripheral *periph;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+- if (!pmc || !name || !parent_name || id > PERIPHERAL_ID_MAX)
++ if (!name || !parent_name || id > PERIPHERAL_ID_MAX)
+ return ERR_PTR(-EINVAL);
+
+ periph = kzalloc(sizeof(*periph), GFP_KERNEL);
+@@ -123,7 +129,7 @@ at91_clk_register_peripheral(struct at91
+
+ periph->id = id;
+ periph->hw.init = &init;
+- periph->pmc = pmc;
++ periph->regmap = regmap;
+
+ clk = clk_register(NULL, &periph->hw);
+ if (IS_ERR(clk))
+@@ -160,53 +166,58 @@ static void clk_sam9x5_peripheral_autodi
+ static int clk_sam9x5_peripheral_enable(struct clk_hw *hw)
+ {
+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
+- struct at91_pmc *pmc = periph->pmc;
+- u32 tmp;
++ unsigned long flags;
+
+ if (periph->id < PERIPHERAL_ID_MIN)
+ return 0;
+
+- pmc_lock(pmc);
+- pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
+- tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_DIV_MASK;
+- pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_DIV(periph->div)
+- | AT91_PMC_PCR_CMD
+- | AT91_PMC_PCR_EN);
+- pmc_unlock(pmc);
++ spin_lock_irqsave(periph->lock, flags);
++ regmap_write(periph->regmap, AT91_PMC_PCR,
++ (periph->id & AT91_PMC_PCR_PID_MASK));
++ regmap_update_bits(periph->regmap, AT91_PMC_PCR,
++ AT91_PMC_PCR_DIV_MASK | AT91_PMC_PCR_CMD |
++ AT91_PMC_PCR_EN,
++ AT91_PMC_PCR_DIV(periph->div) |
++ AT91_PMC_PCR_CMD |
++ AT91_PMC_PCR_EN);
++ spin_unlock_irqrestore(periph->lock, flags);
++
+ return 0;
+ }
+
+ static void clk_sam9x5_peripheral_disable(struct clk_hw *hw)
+ {
+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
+- struct at91_pmc *pmc = periph->pmc;
+- u32 tmp;
++ unsigned long flags;
+
+ if (periph->id < PERIPHERAL_ID_MIN)
+ return;
+
+- pmc_lock(pmc);
+- pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
+- tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_EN;
+- pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD);
+- pmc_unlock(pmc);
++ spin_lock_irqsave(periph->lock, flags);
++ regmap_write(periph->regmap, AT91_PMC_PCR,
++ (periph->id & AT91_PMC_PCR_PID_MASK));
++ regmap_update_bits(periph->regmap, AT91_PMC_PCR,
++ AT91_PMC_PCR_EN | AT91_PMC_PCR_CMD,
++ AT91_PMC_PCR_CMD);
++ spin_unlock_irqrestore(periph->lock, flags);
+ }
+
+ static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
+ {
+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
+- struct at91_pmc *pmc = periph->pmc;
+- int ret;
++ unsigned long flags;
++ unsigned int status;
+
+ if (periph->id < PERIPHERAL_ID_MIN)
+ return 1;
+
+- pmc_lock(pmc);
+- pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
+- ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN);
+- pmc_unlock(pmc);
++ spin_lock_irqsave(periph->lock, flags);
++ regmap_write(periph->regmap, AT91_PMC_PCR,
++ (periph->id & AT91_PMC_PCR_PID_MASK));
++ regmap_read(periph->regmap, AT91_PMC_PCR, &status);
++ spin_unlock_irqrestore(periph->lock, flags);
+
+- return ret;
++ return status & AT91_PMC_PCR_EN ? 1 : 0;
+ }
+
+ static unsigned long
+@@ -214,19 +225,20 @@ clk_sam9x5_peripheral_recalc_rate(struct
+ unsigned long parent_rate)
+ {
+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
+- struct at91_pmc *pmc = periph->pmc;
+- u32 tmp;
++ unsigned long flags;
++ unsigned int status;
+
+ if (periph->id < PERIPHERAL_ID_MIN)
+ return parent_rate;
+
+- pmc_lock(pmc);
+- pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
+- tmp = pmc_read(pmc, AT91_PMC_PCR);
+- pmc_unlock(pmc);
++ spin_lock_irqsave(periph->lock, flags);
++ regmap_write(periph->regmap, AT91_PMC_PCR,
++ (periph->id & AT91_PMC_PCR_PID_MASK));
++ regmap_read(periph->regmap, AT91_PMC_PCR, &status);
++ spin_unlock_irqrestore(periph->lock, flags);
+
+- if (tmp & AT91_PMC_PCR_EN) {
+- periph->div = PERIPHERAL_RSHIFT(tmp);
++ if (status & AT91_PMC_PCR_EN) {
++ periph->div = PERIPHERAL_RSHIFT(status);
+ periph->auto_div = false;
+ } else {
+ clk_sam9x5_peripheral_autodiv(periph);
+@@ -318,15 +330,15 @@ static const struct clk_ops sam9x5_perip
+ };
+
+ static struct clk * __init
+-at91_clk_register_sam9x5_peripheral(struct at91_pmc *pmc, const char *name,
+- const char *parent_name, u32 id,
+- const struct clk_range *range)
++at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
++ const char *name, const char *parent_name,
++ u32 id, const struct clk_range *range)
+ {
+ struct clk_sam9x5_peripheral *periph;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+- if (!pmc || !name || !parent_name)
++ if (!name || !parent_name)
+ return ERR_PTR(-EINVAL);
+
+ periph = kzalloc(sizeof(*periph), GFP_KERNEL);
+@@ -342,7 +354,8 @@ at91_clk_register_sam9x5_peripheral(stru
+ periph->id = id;
+ periph->hw.init = &init;
+ periph->div = 0;
+- periph->pmc = pmc;
++ periph->regmap = regmap;
++ periph->lock = lock;
+ periph->auto_div = true;
+ periph->range = *range;
+
+@@ -356,7 +369,7 @@ at91_clk_register_sam9x5_peripheral(stru
+ }
+
+ static void __init
+-of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type)
++of_at91_clk_periph_setup(struct device_node *np, u8 type)
+ {
+ int num;
+ u32 id;
+@@ -364,6 +377,7 @@ of_at91_clk_periph_setup(struct device_n
+ const char *parent_name;
+ const char *name;
+ struct device_node *periphclknp;
++ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name)
+@@ -373,6 +387,10 @@ of_at91_clk_periph_setup(struct device_n
+ if (!num || num > PERIPHERAL_MAX)
+ return;
+
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
+ for_each_child_of_node(np, periphclknp) {
+ if (of_property_read_u32(periphclknp, "reg", &id))
+ continue;
+@@ -384,7 +402,7 @@ of_at91_clk_periph_setup(struct device_n
+ name = periphclknp->name;
+
+ if (type == PERIPHERAL_AT91RM9200) {
+- clk = at91_clk_register_peripheral(pmc, name,
++ clk = at91_clk_register_peripheral(regmap, name,
+ parent_name, id);
+ } else {
+ struct clk_range range = CLK_RANGE(0, 0);
+@@ -393,7 +411,9 @@ of_at91_clk_periph_setup(struct device_n
+ "atmel,clk-output-range",
+ &range);
+
+- clk = at91_clk_register_sam9x5_peripheral(pmc, name,
++ clk = at91_clk_register_sam9x5_peripheral(regmap,
++ &pmc_pcr_lock,
++ name,
+ parent_name,
+ id, &range);
+ }
+@@ -405,14 +425,16 @@ of_at91_clk_periph_setup(struct device_n
+ }
+ }
+
+-void __init of_at91rm9200_clk_periph_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91rm9200_clk_periph_setup(struct device_node *np)
+ {
+- of_at91_clk_periph_setup(np, pmc, PERIPHERAL_AT91RM9200);
++ of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
+ }
++CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
++ of_at91rm9200_clk_periph_setup);
+
+-void __init of_at91sam9x5_clk_periph_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np)
+ {
+- of_at91_clk_periph_setup(np, pmc, PERIPHERAL_AT91SAM9X5);
++ of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
+ }
++CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
++ of_at91sam9x5_clk_periph_setup);
+--- a/drivers/clk/at91/clk-pll.c
++++ b/drivers/clk/at91/clk-pll.c
+@@ -20,6 +20,8 @@
+ #include <linux/sched.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include "pmc.h"
+
+@@ -58,7 +60,7 @@ struct clk_pll_layout {
+
+ struct clk_pll {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ u8 id;
+@@ -79,10 +81,19 @@ static irqreturn_t clk_pll_irq_handler(i
+ return IRQ_HANDLED;
+ }
+
++static inline bool clk_pll_ready(struct regmap *regmap, int id)
++{
++ unsigned int status;
++
++ regmap_read(regmap, AT91_PMC_SR, &status);
++
++ return status & PLL_STATUS_MASK(id) ? 1 : 0;
++}
++
+ static int clk_pll_prepare(struct clk_hw *hw)
+ {
+ struct clk_pll *pll = to_clk_pll(hw);
+- struct at91_pmc *pmc = pll->pmc;
++ struct regmap *regmap = pll->regmap;
+ const struct clk_pll_layout *layout = pll->layout;
+ const struct clk_pll_characteristics *characteristics =
+ pll->characteristics;
+@@ -90,38 +101,36 @@ static int clk_pll_prepare(struct clk_hw
+ u32 mask = PLL_STATUS_MASK(id);
+ int offset = PLL_REG(id);
+ u8 out = 0;
+- u32 pllr, icpr;
++ unsigned int pllr;
++ unsigned int status;
+ u8 div;
+ u16 mul;
+
+- pllr = pmc_read(pmc, offset);
++ regmap_read(regmap, offset, &pllr);
+ div = PLL_DIV(pllr);
+ mul = PLL_MUL(pllr, layout);
+
+- if ((pmc_read(pmc, AT91_PMC_SR) & mask) &&
++ regmap_read(regmap, AT91_PMC_SR, &status);
++ if ((status & mask) &&
+ (div == pll->div && mul == pll->mul))
+ return 0;
+
+ if (characteristics->out)
+ out = characteristics->out[pll->range];
+- if (characteristics->icpll) {
+- icpr = pmc_read(pmc, AT91_PMC_PLLICPR) & ~PLL_ICPR_MASK(id);
+- icpr |= (characteristics->icpll[pll->range] <<
+- PLL_ICPR_SHIFT(id));
+- pmc_write(pmc, AT91_PMC_PLLICPR, icpr);
+- }
+
+- pllr &= ~layout->pllr_mask;
+- pllr |= layout->pllr_mask &
+- (pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) |
+- (out << PLL_OUT_SHIFT) |
+- ((pll->mul & layout->mul_mask) << layout->mul_shift));
+- pmc_write(pmc, offset, pllr);
++ if (characteristics->icpll)
++ regmap_update_bits(regmap, AT91_PMC_PLLICPR, PLL_ICPR_MASK(id),
++ characteristics->icpll[pll->range] << PLL_ICPR_SHIFT(id));
++
++ regmap_update_bits(regmap, offset, layout->pllr_mask,
++ pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) |
++ (out << PLL_OUT_SHIFT) |
++ ((pll->mul & layout->mul_mask) << layout->mul_shift));
+
+- while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) {
++ while (!clk_pll_ready(regmap, pll->id)) {
+ enable_irq(pll->irq);
+ wait_event(pll->wait,
+- pmc_read(pmc, AT91_PMC_SR) & mask);
++ clk_pll_ready(regmap, pll->id));
+ }
+
+ return 0;
+@@ -130,32 +139,35 @@ static int clk_pll_prepare(struct clk_hw
+ static int clk_pll_is_prepared(struct clk_hw *hw)
+ {
+ struct clk_pll *pll = to_clk_pll(hw);
+- struct at91_pmc *pmc = pll->pmc;
+
+- return !!(pmc_read(pmc, AT91_PMC_SR) &
+- PLL_STATUS_MASK(pll->id));
++ return clk_pll_ready(pll->regmap, pll->id);
+ }
+
+ static void clk_pll_unprepare(struct clk_hw *hw)
+ {
+ struct clk_pll *pll = to_clk_pll(hw);
+- struct at91_pmc *pmc = pll->pmc;
+- const struct clk_pll_layout *layout = pll->layout;
+- int offset = PLL_REG(pll->id);
+- u32 tmp = pmc_read(pmc, offset) & ~(layout->pllr_mask);
++ unsigned int mask = pll->layout->pllr_mask;
+
+- pmc_write(pmc, offset, tmp);
++ regmap_update_bits(pll->regmap, PLL_REG(pll->id), mask, ~mask);
+ }
+
+ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+ struct clk_pll *pll = to_clk_pll(hw);
++ unsigned int pllr;
++ u16 mul;
++ u8 div;
++
++ regmap_read(pll->regmap, PLL_REG(pll->id), &pllr);
++
++ div = PLL_DIV(pllr);
++ mul = PLL_MUL(pllr, pll->layout);
+
+- if (!pll->div || !pll->mul)
++ if (!div || !mul)
+ return 0;
+
+- return (parent_rate / pll->div) * (pll->mul + 1);
++ return (parent_rate / div) * (mul + 1);
+ }
+
+ static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate,
+@@ -308,7 +320,7 @@ static const struct clk_ops pll_ops = {
+ };
+
+ static struct clk * __init
+-at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name,
++at91_clk_register_pll(struct regmap *regmap, unsigned int irq, const char *name,
+ const char *parent_name, u8 id,
+ const struct clk_pll_layout *layout,
+ const struct clk_pll_characteristics *characteristics)
+@@ -318,7 +330,7 @@ at91_clk_register_pll(struct at91_pmc *p
+ struct clk_init_data init;
+ int ret;
+ int offset = PLL_REG(id);
+- u32 tmp;
++ unsigned int pllr;
+
+ if (id > PLL_MAX_ID)
+ return ERR_PTR(-EINVAL);
+@@ -337,11 +349,11 @@ at91_clk_register_pll(struct at91_pmc *p
+ pll->hw.init = &init;
+ pll->layout = layout;
+ pll->characteristics = characteristics;
+- pll->pmc = pmc;
++ pll->regmap = regmap;
+ pll->irq = irq;
+- tmp = pmc_read(pmc, offset) & layout->pllr_mask;
+- pll->div = PLL_DIV(tmp);
+- pll->mul = PLL_MUL(tmp, layout);
++ regmap_read(regmap, offset, &pllr);
++ pll->div = PLL_DIV(pllr);
++ pll->mul = PLL_MUL(pllr, layout);
+ init_waitqueue_head(&pll->wait);
+ irq_set_status_flags(pll->irq, IRQ_NOAUTOEN);
+ ret = request_irq(pll->irq, clk_pll_irq_handler, IRQF_TRIGGER_HIGH,
+@@ -483,12 +495,13 @@ of_at91_clk_pll_get_characteristics(stru
+ }
+
+ static void __init
+-of_at91_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc,
++of_at91_clk_pll_setup(struct device_node *np,
+ const struct clk_pll_layout *layout)
+ {
+ u32 id;
+ unsigned int irq;
+ struct clk *clk;
++ struct regmap *regmap;
+ const char *parent_name;
+ const char *name = np->name;
+ struct clk_pll_characteristics *characteristics;
+@@ -500,6 +513,10 @@ of_at91_clk_pll_setup(struct device_node
+
+ of_property_read_string(np, "clock-output-names", &name);
+
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
+ characteristics = of_at91_clk_pll_get_characteristics(np);
+ if (!characteristics)
+ return;
+@@ -508,7 +525,7 @@ of_at91_clk_pll_setup(struct device_node
+ if (!irq)
+ return;
+
+- clk = at91_clk_register_pll(pmc, irq, name, parent_name, id, layout,
++ clk = at91_clk_register_pll(regmap, irq, name, parent_name, id, layout,
+ characteristics);
+ if (IS_ERR(clk))
+ goto out_free_characteristics;
+@@ -520,26 +537,30 @@ of_at91_clk_pll_setup(struct device_node
+ kfree(characteristics);
+ }
+
+-void __init of_at91rm9200_clk_pll_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91rm9200_clk_pll_setup(struct device_node *np)
+ {
+- of_at91_clk_pll_setup(np, pmc, &at91rm9200_pll_layout);
++ of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
+ }
++CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
++ of_at91rm9200_clk_pll_setup);
+
+-void __init of_at91sam9g45_clk_pll_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np)
+ {
+- of_at91_clk_pll_setup(np, pmc, &at91sam9g45_pll_layout);
++ of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
+ }
++CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
++ of_at91sam9g45_clk_pll_setup);
+
+-void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np)
+ {
+- of_at91_clk_pll_setup(np, pmc, &at91sam9g20_pllb_layout);
++ of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
+ }
++CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
++ of_at91sam9g20_clk_pllb_setup);
+
+-void __init of_sama5d3_clk_pll_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_sama5d3_clk_pll_setup(struct device_node *np)
+ {
+- of_at91_clk_pll_setup(np, pmc, &sama5d3_pll_layout);
++ of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
+ }
++CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
++ of_sama5d3_clk_pll_setup);
+--- a/drivers/clk/at91/clk-plldiv.c
++++ b/drivers/clk/at91/clk-plldiv.c
+@@ -14,6 +14,8 @@
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/io.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include "pmc.h"
+
+@@ -21,16 +23,18 @@
+
+ struct clk_plldiv {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ };
+
+ static unsigned long clk_plldiv_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+ struct clk_plldiv *plldiv = to_clk_plldiv(hw);
+- struct at91_pmc *pmc = plldiv->pmc;
++ unsigned int mckr;
+
+- if (pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_PLLADIV2)
++ regmap_read(plldiv->regmap, AT91_PMC_MCKR, &mckr);
++
++ if (mckr & AT91_PMC_PLLADIV2)
+ return parent_rate / 2;
+
+ return parent_rate;
+@@ -57,18 +61,12 @@ static int clk_plldiv_set_rate(struct cl
+ unsigned long parent_rate)
+ {
+ struct clk_plldiv *plldiv = to_clk_plldiv(hw);
+- struct at91_pmc *pmc = plldiv->pmc;
+- u32 tmp;
+
+- if (parent_rate != rate && (parent_rate / 2) != rate)
++ if ((parent_rate != rate) && (parent_rate / 2 != rate))
+ return -EINVAL;
+
+- pmc_lock(pmc);
+- tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_PLLADIV2;
+- if ((parent_rate / 2) == rate)
+- tmp |= AT91_PMC_PLLADIV2;
+- pmc_write(pmc, AT91_PMC_MCKR, tmp);
+- pmc_unlock(pmc);
++ regmap_update_bits(plldiv->regmap, AT91_PMC_MCKR, AT91_PMC_PLLADIV2,
++ parent_rate != rate ? AT91_PMC_PLLADIV2 : 0);
+
+ return 0;
+ }
+@@ -80,7 +78,7 @@ static const struct clk_ops plldiv_ops =
+ };
+
+ static struct clk * __init
+-at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name,
++at91_clk_register_plldiv(struct regmap *regmap, const char *name,
+ const char *parent_name)
+ {
+ struct clk_plldiv *plldiv;
+@@ -98,7 +96,7 @@ at91_clk_register_plldiv(struct at91_pmc
+ init.flags = CLK_SET_RATE_GATE;
+
+ plldiv->hw.init = &init;
+- plldiv->pmc = pmc;
++ plldiv->regmap = regmap;
+
+ clk = clk_register(NULL, &plldiv->hw);
+
+@@ -109,27 +107,27 @@ at91_clk_register_plldiv(struct at91_pmc
+ }
+
+ static void __init
+-of_at91_clk_plldiv_setup(struct device_node *np, struct at91_pmc *pmc)
++of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
+ {
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
++ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+- clk = at91_clk_register_plldiv(pmc, name, parent_name);
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
+
++ clk = at91_clk_register_plldiv(regmap, name, parent_name);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ return;
+ }
+-
+-void __init of_at91sam9x5_clk_plldiv_setup(struct device_node *np,
+- struct at91_pmc *pmc)
+-{
+- of_at91_clk_plldiv_setup(np, pmc);
+-}
++CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
++ of_at91sam9x5_clk_plldiv_setup);
+--- a/drivers/clk/at91/clk-programmable.c
++++ b/drivers/clk/at91/clk-programmable.c
+@@ -16,6 +16,8 @@
+ #include <linux/io.h>
+ #include <linux/wait.h>
+ #include <linux/sched.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include "pmc.h"
+
+@@ -24,6 +26,7 @@
+
+ #define PROG_STATUS_MASK(id) (1 << ((id) + 8))
+ #define PROG_PRES_MASK 0x7
++#define PROG_PRES(layout, pckr) ((pckr >> layout->pres_shift) & PROG_PRES_MASK)
+ #define PROG_MAX_RM9200_CSS 3
+
+ struct clk_programmable_layout {
+@@ -34,7 +37,7 @@ struct clk_programmable_layout {
+
+ struct clk_programmable {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ u8 id;
+ const struct clk_programmable_layout *layout;
+ };
+@@ -44,14 +47,12 @@ struct clk_programmable {
+ static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+- u32 pres;
+ struct clk_programmable *prog = to_clk_programmable(hw);
+- struct at91_pmc *pmc = prog->pmc;
+- const struct clk_programmable_layout *layout = prog->layout;
++ unsigned int pckr;
++
++ regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr);
+
+- pres = (pmc_read(pmc, AT91_PMC_PCKR(prog->id)) >> layout->pres_shift) &
+- PROG_PRES_MASK;
+- return parent_rate >> pres;
++ return parent_rate >> PROG_PRES(prog->layout, pckr);
+ }
+
+ static int clk_programmable_determine_rate(struct clk_hw *hw,
+@@ -101,36 +102,36 @@ static int clk_programmable_set_parent(s
+ {
+ struct clk_programmable *prog = to_clk_programmable(hw);
+ const struct clk_programmable_layout *layout = prog->layout;
+- struct at91_pmc *pmc = prog->pmc;
+- u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) & ~layout->css_mask;
++ unsigned int mask = layout->css_mask;
++ unsigned int pckr = 0;
+
+ if (layout->have_slck_mck)
+- tmp &= AT91_PMC_CSSMCK_MCK;
++ mask |= AT91_PMC_CSSMCK_MCK;
+
+ if (index > layout->css_mask) {
+- if (index > PROG_MAX_RM9200_CSS && layout->have_slck_mck) {
+- tmp |= AT91_PMC_CSSMCK_MCK;
+- return 0;
+- } else {
++ if (index > PROG_MAX_RM9200_CSS && !layout->have_slck_mck)
+ return -EINVAL;
+- }
++
++ pckr |= AT91_PMC_CSSMCK_MCK;
+ }
+
+- pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | index);
++ regmap_update_bits(prog->regmap, AT91_PMC_PCKR(prog->id), mask, pckr);
++
+ return 0;
+ }
+
+ static u8 clk_programmable_get_parent(struct clk_hw *hw)
+ {
+- u32 tmp;
+- u8 ret;
+ struct clk_programmable *prog = to_clk_programmable(hw);
+- struct at91_pmc *pmc = prog->pmc;
+ const struct clk_programmable_layout *layout = prog->layout;
++ unsigned int pckr;
++ u8 ret;
++
++ regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr);
++
++ ret = pckr & layout->css_mask;
+
+- tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
+- ret = tmp & layout->css_mask;
+- if (layout->have_slck_mck && (tmp & AT91_PMC_CSSMCK_MCK) && !ret)
++ if (layout->have_slck_mck && (pckr & AT91_PMC_CSSMCK_MCK) && !ret)
+ ret = PROG_MAX_RM9200_CSS + 1;
+
+ return ret;
+@@ -140,26 +141,27 @@ static int clk_programmable_set_rate(str
+ unsigned long parent_rate)
+ {
+ struct clk_programmable *prog = to_clk_programmable(hw);
+- struct at91_pmc *pmc = prog->pmc;
+ const struct clk_programmable_layout *layout = prog->layout;
+ unsigned long div = parent_rate / rate;
++ unsigned int pckr;
+ int shift = 0;
+- u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) &
+- ~(PROG_PRES_MASK << layout->pres_shift);
++
++ regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr);
+
+ if (!div)
+ return -EINVAL;
+
+ shift = fls(div) - 1;
+
+- if (div != (1<<shift))
++ if (div != (1 << shift))
+ return -EINVAL;
+
+ if (shift >= PROG_PRES_MASK)
+ return -EINVAL;
+
+- pmc_write(pmc, AT91_PMC_PCKR(prog->id),
+- tmp | (shift << layout->pres_shift));
++ regmap_update_bits(prog->regmap, AT91_PMC_PCKR(prog->id),
++ PROG_PRES_MASK << layout->pres_shift,
++ shift << layout->pres_shift);
+
+ return 0;
+ }
+@@ -173,7 +175,7 @@ static const struct clk_ops programmable
+ };
+
+ static struct clk * __init
+-at91_clk_register_programmable(struct at91_pmc *pmc,
++at91_clk_register_programmable(struct regmap *regmap,
+ const char *name, const char **parent_names,
+ u8 num_parents, u8 id,
+ const struct clk_programmable_layout *layout)
+@@ -198,7 +200,7 @@ at91_clk_register_programmable(struct at
+ prog->id = id;
+ prog->layout = layout;
+ prog->hw.init = &init;
+- prog->pmc = pmc;
++ prog->regmap = regmap;
+
+ clk = clk_register(NULL, &prog->hw);
+ if (IS_ERR(clk))
+@@ -226,7 +228,7 @@ static const struct clk_programmable_lay
+ };
+
+ static void __init
+-of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc,
++of_at91_clk_prog_setup(struct device_node *np,
+ const struct clk_programmable_layout *layout)
+ {
+ int num;
+@@ -236,6 +238,7 @@ of_at91_clk_prog_setup(struct device_nod
+ const char *parent_names[PROG_SOURCE_MAX];
+ const char *name;
+ struct device_node *progclknp;
++ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX)
+@@ -247,6 +250,10 @@ of_at91_clk_prog_setup(struct device_nod
+ if (!num || num > (PROG_ID_MAX + 1))
+ return;
+
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
+ for_each_child_of_node(np, progclknp) {
+ if (of_property_read_u32(progclknp, "reg", &id))
+ continue;
+@@ -254,7 +261,7 @@ of_at91_clk_prog_setup(struct device_nod
+ if (of_property_read_string(np, "clock-output-names", &name))
+ name = progclknp->name;
+
+- clk = at91_clk_register_programmable(pmc, name,
++ clk = at91_clk_register_programmable(regmap, name,
+ parent_names, num_parents,
+ id, layout);
+ if (IS_ERR(clk))
+@@ -265,20 +272,23 @@ of_at91_clk_prog_setup(struct device_nod
+ }
+
+
+-void __init of_at91rm9200_clk_prog_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
+ {
+- of_at91_clk_prog_setup(np, pmc, &at91rm9200_programmable_layout);
++ of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout);
+ }
++CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
++ of_at91rm9200_clk_prog_setup);
+
+-void __init of_at91sam9g45_clk_prog_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np)
+ {
+- of_at91_clk_prog_setup(np, pmc, &at91sam9g45_programmable_layout);
++ of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout);
+ }
++CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
++ of_at91sam9g45_clk_prog_setup);
+
+-void __init of_at91sam9x5_clk_prog_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np)
+ {
+- of_at91_clk_prog_setup(np, pmc, &at91sam9x5_programmable_layout);
++ of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout);
+ }
++CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
++ of_at91sam9x5_clk_prog_setup);
+--- a/drivers/clk/at91/clk-slow.c
++++ b/drivers/clk/at91/clk-slow.c
+@@ -22,6 +22,8 @@
+ #include <linux/io.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+ #include <linux/sched.h>
+ #include <linux/wait.h>
+
+@@ -59,7 +61,7 @@ struct clk_slow_rc_osc {
+
+ struct clk_sam9260_slow {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ };
+
+ #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw)
+@@ -393,8 +395,11 @@ void __init of_at91sam9x5_clk_slow_setup
+ static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw)
+ {
+ struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw);
++ unsigned int status;
+
+- return !!(pmc_read(slowck->pmc, AT91_PMC_SR) & AT91_PMC_OSCSEL);
++ regmap_read(slowck->regmap, AT91_PMC_SR, &status);
++
++ return status & AT91_PMC_OSCSEL ? 1 : 0;
+ }
+
+ static const struct clk_ops sam9260_slow_ops = {
+@@ -402,7 +407,7 @@ static const struct clk_ops sam9260_slow
+ };
+
+ static struct clk * __init
+-at91_clk_register_sam9260_slow(struct at91_pmc *pmc,
++at91_clk_register_sam9260_slow(struct regmap *regmap,
+ const char *name,
+ const char **parent_names,
+ int num_parents)
+@@ -411,7 +416,7 @@ at91_clk_register_sam9260_slow(struct at
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+- if (!pmc || !name)
++ if (!name)
+ return ERR_PTR(-EINVAL);
+
+ if (!parent_names || !num_parents)
+@@ -428,7 +433,7 @@ at91_clk_register_sam9260_slow(struct at
+ init.flags = 0;
+
+ slowck->hw.init = &init;
+- slowck->pmc = pmc;
++ slowck->regmap = regmap;
+
+ clk = clk_register(NULL, &slowck->hw);
+ if (IS_ERR(clk))
+@@ -439,29 +444,34 @@ at91_clk_register_sam9260_slow(struct at
+ return clk;
+ }
+
+-void __init of_at91sam9260_clk_slow_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
+ {
+ struct clk *clk;
+ const char *parent_names[2];
+ int num_parents;
+ const char *name = np->name;
++ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents != 2)
+ return;
+
+ of_clk_parent_fill(np, parent_names, num_parents);
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+- clk = at91_clk_register_sam9260_slow(pmc, name, parent_names,
++ clk = at91_clk_register_sam9260_slow(regmap, name, parent_names,
+ num_parents);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ }
++CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
++ of_at91sam9260_clk_slow_setup);
+
+ /*
+ * FIXME: All slow clk users are not properly claiming it (get + prepare +
+--- a/drivers/clk/at91/clk-smd.c
++++ b/drivers/clk/at91/clk-smd.c
+@@ -14,6 +14,8 @@
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/io.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include "pmc.h"
+
+@@ -24,7 +26,7 @@
+
+ struct at91sam9x5_clk_smd {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ };
+
+ #define to_at91sam9x5_clk_smd(hw) \
+@@ -33,13 +35,13 @@ struct at91sam9x5_clk_smd {
+ static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+- u32 tmp;
+- u8 smddiv;
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+- struct at91_pmc *pmc = smd->pmc;
++ unsigned int smdr;
++ u8 smddiv;
++
++ regmap_read(smd->regmap, AT91_PMC_SMD, &smdr);
++ smddiv = (smdr & AT91_PMC_SMD_DIV) >> SMD_DIV_SHIFT;
+
+- tmp = pmc_read(pmc, AT91_PMC_SMD);
+- smddiv = (tmp & AT91_PMC_SMD_DIV) >> SMD_DIV_SHIFT;
+ return parent_rate / (smddiv + 1);
+ }
+
+@@ -67,40 +69,38 @@ static long at91sam9x5_clk_smd_round_rat
+
+ static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index)
+ {
+- u32 tmp;
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+- struct at91_pmc *pmc = smd->pmc;
+
+ if (index > 1)
+ return -EINVAL;
+- tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMDS;
+- if (index)
+- tmp |= AT91_PMC_SMDS;
+- pmc_write(pmc, AT91_PMC_SMD, tmp);
++
++ regmap_update_bits(smd->regmap, AT91_PMC_SMD, AT91_PMC_SMDS,
++ index ? AT91_PMC_SMDS : 0);
++
+ return 0;
+ }
+
+ static u8 at91sam9x5_clk_smd_get_parent(struct clk_hw *hw)
+ {
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+- struct at91_pmc *pmc = smd->pmc;
++ unsigned int smdr;
+
+- return pmc_read(pmc, AT91_PMC_SMD) & AT91_PMC_SMDS;
++ regmap_read(smd->regmap, AT91_PMC_SMD, &smdr);
++
++ return smdr & AT91_PMC_SMDS;
+ }
+
+ static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+ {
+- u32 tmp;
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+- struct at91_pmc *pmc = smd->pmc;
+ unsigned long div = parent_rate / rate;
+
+ if (parent_rate % rate || div < 1 || div > (SMD_MAX_DIV + 1))
+ return -EINVAL;
+- tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMD_DIV;
+- tmp |= (div - 1) << SMD_DIV_SHIFT;
+- pmc_write(pmc, AT91_PMC_SMD, tmp);
++
++ regmap_update_bits(smd->regmap, AT91_PMC_SMD, AT91_PMC_SMD_DIV,
++ (div - 1) << SMD_DIV_SHIFT);
+
+ return 0;
+ }
+@@ -114,7 +114,7 @@ static const struct clk_ops at91sam9x5_s
+ };
+
+ static struct clk * __init
+-at91sam9x5_clk_register_smd(struct at91_pmc *pmc, const char *name,
++at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
+ const char **parent_names, u8 num_parents)
+ {
+ struct at91sam9x5_clk_smd *smd;
+@@ -132,7 +132,7 @@ at91sam9x5_clk_register_smd(struct at91_
+ init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
+
+ smd->hw.init = &init;
+- smd->pmc = pmc;
++ smd->regmap = regmap;
+
+ clk = clk_register(NULL, &smd->hw);
+ if (IS_ERR(clk))
+@@ -141,13 +141,13 @@ at91sam9x5_clk_register_smd(struct at91_
+ return clk;
+ }
+
+-void __init of_at91sam9x5_clk_smd_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
+ {
+ struct clk *clk;
+ int num_parents;
+ const char *parent_names[SMD_SOURCE_MAX];
+ const char *name = np->name;
++ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX)
+@@ -157,10 +157,16 @@ void __init of_at91sam9x5_clk_smd_setup(
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+- clk = at91sam9x5_clk_register_smd(pmc, name, parent_names,
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
++ clk = at91sam9x5_clk_register_smd(regmap, name, parent_names,
+ num_parents);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ }
++CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
++ of_at91sam9x5_clk_smd_setup);
+--- a/drivers/clk/at91/clk-system.c
++++ b/drivers/clk/at91/clk-system.c
+@@ -19,6 +19,8 @@
+ #include <linux/interrupt.h>
+ #include <linux/wait.h>
+ #include <linux/sched.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include "pmc.h"
+
+@@ -29,7 +31,7 @@
+ #define to_clk_system(hw) container_of(hw, struct clk_system, hw)
+ struct clk_system {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ u8 id;
+@@ -49,24 +51,32 @@ static irqreturn_t clk_system_irq_handle
+ return IRQ_HANDLED;
+ }
+
++static inline bool clk_system_ready(struct regmap *regmap, int id)
++{
++ unsigned int status;
++
++ regmap_read(regmap, AT91_PMC_SR, &status);
++
++ return status & (1 << id) ? 1 : 0;
++}
++
+ static int clk_system_prepare(struct clk_hw *hw)
+ {
+ struct clk_system *sys = to_clk_system(hw);
+- struct at91_pmc *pmc = sys->pmc;
+- u32 mask = 1 << sys->id;
+
+- pmc_write(pmc, AT91_PMC_SCER, mask);
++ regmap_write(sys->regmap, AT91_PMC_SCER, 1 << sys->id);
+
+ if (!is_pck(sys->id))
+ return 0;
+
+- while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) {
++ while (!clk_system_ready(sys->regmap, sys->id)) {
+ if (sys->irq) {
+ enable_irq(sys->irq);
+ wait_event(sys->wait,
+- pmc_read(pmc, AT91_PMC_SR) & mask);
+- } else
++ clk_system_ready(sys->regmap, sys->id));
++ } else {
+ cpu_relax();
++ }
+ }
+ return 0;
+ }
+@@ -74,23 +84,26 @@ static int clk_system_prepare(struct clk
+ static void clk_system_unprepare(struct clk_hw *hw)
+ {
+ struct clk_system *sys = to_clk_system(hw);
+- struct at91_pmc *pmc = sys->pmc;
+
+- pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id);
++ regmap_write(sys->regmap, AT91_PMC_SCDR, 1 << sys->id);
+ }
+
+ static int clk_system_is_prepared(struct clk_hw *hw)
+ {
+ struct clk_system *sys = to_clk_system(hw);
+- struct at91_pmc *pmc = sys->pmc;
++ unsigned int status;
++
++ regmap_read(sys->regmap, AT91_PMC_SCSR, &status);
+
+- if (!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id)))
++ if (!(status & (1 << sys->id)))
+ return 0;
+
+ if (!is_pck(sys->id))
+ return 1;
+
+- return !!(pmc_read(pmc, AT91_PMC_SR) & (1 << sys->id));
++ regmap_read(sys->regmap, AT91_PMC_SR, &status);
++
++ return status & (1 << sys->id) ? 1 : 0;
+ }
+
+ static const struct clk_ops system_ops = {
+@@ -100,7 +113,7 @@ static const struct clk_ops system_ops =
+ };
+
+ static struct clk * __init
+-at91_clk_register_system(struct at91_pmc *pmc, const char *name,
++at91_clk_register_system(struct regmap *regmap, const char *name,
+ const char *parent_name, u8 id, int irq)
+ {
+ struct clk_system *sys;
+@@ -123,7 +136,7 @@ at91_clk_register_system(struct at91_pmc
+
+ sys->id = id;
+ sys->hw.init = &init;
+- sys->pmc = pmc;
++ sys->regmap = regmap;
+ sys->irq = irq;
+ if (irq) {
+ init_waitqueue_head(&sys->wait);
+@@ -146,8 +159,7 @@ at91_clk_register_system(struct at91_pmc
+ return clk;
+ }
+
+-static void __init
+-of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
++static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
+ {
+ int num;
+ int irq = 0;
+@@ -156,11 +168,16 @@ of_at91_clk_sys_setup(struct device_node
+ const char *name;
+ struct device_node *sysclknp;
+ const char *parent_name;
++ struct regmap *regmap;
+
+ num = of_get_child_count(np);
+ if (num > (SYSTEM_MAX_ID + 1))
+ return;
+
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
+ for_each_child_of_node(np, sysclknp) {
+ if (of_property_read_u32(sysclknp, "reg", &id))
+ continue;
+@@ -173,16 +190,13 @@ of_at91_clk_sys_setup(struct device_node
+
+ parent_name = of_clk_get_parent_name(sysclknp, 0);
+
+- clk = at91_clk_register_system(pmc, name, parent_name, id, irq);
++ clk = at91_clk_register_system(regmap, name, parent_name, id,
++ irq);
+ if (IS_ERR(clk))
+ continue;
+
+ of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk);
+ }
+ }
+-
+-void __init of_at91rm9200_clk_sys_setup(struct device_node *np,
+- struct at91_pmc *pmc)
+-{
+- of_at91_clk_sys_setup(np, pmc);
+-}
++CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
++ of_at91rm9200_clk_sys_setup);
+--- a/drivers/clk/at91/clk-usb.c
++++ b/drivers/clk/at91/clk-usb.c
+@@ -14,6 +14,8 @@
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/io.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include "pmc.h"
+
+@@ -27,7 +29,7 @@
+
+ struct at91sam9x5_clk_usb {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ };
+
+ #define to_at91sam9x5_clk_usb(hw) \
+@@ -35,7 +37,7 @@ struct at91sam9x5_clk_usb {
+
+ struct at91rm9200_clk_usb {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ u32 divisors[4];
+ };
+
+@@ -45,13 +47,12 @@ struct at91rm9200_clk_usb {
+ static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+- u32 tmp;
+- u8 usbdiv;
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+- struct at91_pmc *pmc = usb->pmc;
++ unsigned int usbr;
++ u8 usbdiv;
+
+- tmp = pmc_read(pmc, AT91_PMC_USB);
+- usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT;
++ regmap_read(usb->regmap, AT91_PMC_USB, &usbr);
++ usbdiv = (usbr & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT;
+
+ return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1));
+ }
+@@ -109,33 +110,31 @@ static int at91sam9x5_clk_usb_determine_
+
+ static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
+ {
+- u32 tmp;
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+- struct at91_pmc *pmc = usb->pmc;
+
+ if (index > 1)
+ return -EINVAL;
+- tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS;
+- if (index)
+- tmp |= AT91_PMC_USBS;
+- pmc_write(pmc, AT91_PMC_USB, tmp);
++
++ regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS,
++ index ? AT91_PMC_USBS : 0);
++
+ return 0;
+ }
+
+ static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw)
+ {
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+- struct at91_pmc *pmc = usb->pmc;
++ unsigned int usbr;
+
+- return pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS;
++ regmap_read(usb->regmap, AT91_PMC_USB, &usbr);
++
++ return usbr & AT91_PMC_USBS;
+ }
+
+ static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+ {
+- u32 tmp;
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+- struct at91_pmc *pmc = usb->pmc;
+ unsigned long div;
+
+ if (!rate)
+@@ -145,9 +144,8 @@ static int at91sam9x5_clk_usb_set_rate(s
+ if (div > SAM9X5_USB_MAX_DIV + 1 || !div)
+ return -EINVAL;
+
+- tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV;
+- tmp |= (div - 1) << SAM9X5_USB_DIV_SHIFT;
+- pmc_write(pmc, AT91_PMC_USB, tmp);
++ regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_OHCIUSBDIV,
++ (div - 1) << SAM9X5_USB_DIV_SHIFT);
+
+ return 0;
+ }
+@@ -163,28 +161,28 @@ static const struct clk_ops at91sam9x5_u
+ static int at91sam9n12_clk_usb_enable(struct clk_hw *hw)
+ {
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+- struct at91_pmc *pmc = usb->pmc;
+
+- pmc_write(pmc, AT91_PMC_USB,
+- pmc_read(pmc, AT91_PMC_USB) | AT91_PMC_USBS);
++ regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS,
++ AT91_PMC_USBS);
++
+ return 0;
+ }
+
+ static void at91sam9n12_clk_usb_disable(struct clk_hw *hw)
+ {
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+- struct at91_pmc *pmc = usb->pmc;
+
+- pmc_write(pmc, AT91_PMC_USB,
+- pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS);
++ regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, 0);
+ }
+
+ static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw)
+ {
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+- struct at91_pmc *pmc = usb->pmc;
++ unsigned int usbr;
+
+- return !!(pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS);
++ regmap_read(usb->regmap, AT91_PMC_USB, &usbr);
++
++ return usbr & AT91_PMC_USBS;
+ }
+
+ static const struct clk_ops at91sam9n12_usb_ops = {
+@@ -197,7 +195,7 @@ static const struct clk_ops at91sam9n12_
+ };
+
+ static struct clk * __init
+-at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name,
++at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
+ const char **parent_names, u8 num_parents)
+ {
+ struct at91sam9x5_clk_usb *usb;
+@@ -216,7 +214,7 @@ at91sam9x5_clk_register_usb(struct at91_
+ CLK_SET_RATE_PARENT;
+
+ usb->hw.init = &init;
+- usb->pmc = pmc;
++ usb->regmap = regmap;
+
+ clk = clk_register(NULL, &usb->hw);
+ if (IS_ERR(clk))
+@@ -226,7 +224,7 @@ at91sam9x5_clk_register_usb(struct at91_
+ }
+
+ static struct clk * __init
+-at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name,
++at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
+ const char *parent_name)
+ {
+ struct at91sam9x5_clk_usb *usb;
+@@ -244,7 +242,7 @@ at91sam9n12_clk_register_usb(struct at91
+ init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT;
+
+ usb->hw.init = &init;
+- usb->pmc = pmc;
++ usb->regmap = regmap;
+
+ clk = clk_register(NULL, &usb->hw);
+ if (IS_ERR(clk))
+@@ -257,12 +255,12 @@ static unsigned long at91rm9200_clk_usb_
+ unsigned long parent_rate)
+ {
+ struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
+- struct at91_pmc *pmc = usb->pmc;
+- u32 tmp;
++ unsigned int pllbr;
+ u8 usbdiv;
+
+- tmp = pmc_read(pmc, AT91_CKGR_PLLBR);
+- usbdiv = (tmp & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT;
++ regmap_read(usb->regmap, AT91_CKGR_PLLBR, &pllbr);
++
++ usbdiv = (pllbr & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT;
+ if (usb->divisors[usbdiv])
+ return parent_rate / usb->divisors[usbdiv];
+
+@@ -310,10 +308,8 @@ static long at91rm9200_clk_usb_round_rat
+ static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+ {
+- u32 tmp;
+ int i;
+ struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
+- struct at91_pmc *pmc = usb->pmc;
+ unsigned long div;
+
+ if (!rate)
+@@ -323,10 +319,10 @@ static int at91rm9200_clk_usb_set_rate(s
+
+ for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) {
+ if (usb->divisors[i] == div) {
+- tmp = pmc_read(pmc, AT91_CKGR_PLLBR) &
+- ~AT91_PMC_USBDIV;
+- tmp |= i << RM9200_USB_DIV_SHIFT;
+- pmc_write(pmc, AT91_CKGR_PLLBR, tmp);
++ regmap_update_bits(usb->regmap, AT91_CKGR_PLLBR,
++ AT91_PMC_USBDIV,
++ i << RM9200_USB_DIV_SHIFT);
++
+ return 0;
+ }
+ }
+@@ -341,7 +337,7 @@ static const struct clk_ops at91rm9200_u
+ };
+
+ static struct clk * __init
+-at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name,
++at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
+ const char *parent_name, const u32 *divisors)
+ {
+ struct at91rm9200_clk_usb *usb;
+@@ -359,7 +355,7 @@ at91rm9200_clk_register_usb(struct at91_
+ init.flags = CLK_SET_RATE_PARENT;
+
+ usb->hw.init = &init;
+- usb->pmc = pmc;
++ usb->regmap = regmap;
+ memcpy(usb->divisors, divisors, sizeof(usb->divisors));
+
+ clk = clk_register(NULL, &usb->hw);
+@@ -369,13 +365,13 @@ at91rm9200_clk_register_usb(struct at91_
+ return clk;
+ }
+
+-void __init of_at91sam9x5_clk_usb_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
+ {
+ struct clk *clk;
+ int num_parents;
+ const char *parent_names[USB_SOURCE_MAX];
+ const char *name = np->name;
++ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents <= 0 || num_parents > USB_SOURCE_MAX)
+@@ -385,19 +381,26 @@ void __init of_at91sam9x5_clk_usb_setup(
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+- clk = at91sam9x5_clk_register_usb(pmc, name, parent_names, num_parents);
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
++ clk = at91sam9x5_clk_register_usb(regmap, name, parent_names,
++ num_parents);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ }
++CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
++ of_at91sam9x5_clk_usb_setup);
+
+-void __init of_at91sam9n12_clk_usb_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
+ {
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
++ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name)
+@@ -405,20 +408,26 @@ void __init of_at91sam9n12_clk_usb_setup
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+- clk = at91sam9n12_clk_register_usb(pmc, name, parent_name);
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
++ clk = at91sam9n12_clk_register_usb(regmap, name, parent_name);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ }
++CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
++ of_at91sam9n12_clk_usb_setup);
+
+-void __init of_at91rm9200_clk_usb_setup(struct device_node *np,
+- struct at91_pmc *pmc)
++static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
+ {
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
+ u32 divisors[4] = {0, 0, 0, 0};
++ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name)
+@@ -430,9 +439,15 @@ void __init of_at91rm9200_clk_usb_setup(
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+- clk = at91rm9200_clk_register_usb(pmc, name, parent_name, divisors);
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
++ clk = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ }
++CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
++ of_at91rm9200_clk_usb_setup);
+--- a/drivers/clk/at91/clk-utmi.c
++++ b/drivers/clk/at91/clk-utmi.c
+@@ -19,6 +19,8 @@
+ #include <linux/io.h>
+ #include <linux/sched.h>
+ #include <linux/wait.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include "pmc.h"
+
+@@ -26,7 +28,7 @@
+
+ struct clk_utmi {
+ struct clk_hw hw;
+- struct at91_pmc *pmc;
++ struct regmap *regmap;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ };
+@@ -43,19 +45,27 @@ static irqreturn_t clk_utmi_irq_handler(
+ return IRQ_HANDLED;
+ }
+
++static inline bool clk_utmi_ready(struct regmap *regmap)
++{
++ unsigned int status;
++
++ regmap_read(regmap, AT91_PMC_SR, &status);
++
++ return status & AT91_PMC_LOCKU;
++}
++
+ static int clk_utmi_prepare(struct clk_hw *hw)
+ {
+ struct clk_utmi *utmi = to_clk_utmi(hw);
+- struct at91_pmc *pmc = utmi->pmc;
+- u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) | AT91_PMC_UPLLEN |
+- AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN;
++ unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
++ AT91_PMC_BIASEN;
+
+- pmc_write(pmc, AT91_CKGR_UCKR, tmp);
++ regmap_update_bits(utmi->regmap, AT91_CKGR_UCKR, uckr, uckr);
+
+- while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU)) {
++ while (!clk_utmi_ready(utmi->regmap)) {
+ enable_irq(utmi->irq);
+ wait_event(utmi->wait,
+- pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU);
++ clk_utmi_ready(utmi->regmap));
+ }
+
+ return 0;
+@@ -64,18 +74,15 @@ static int clk_utmi_prepare(struct clk_h
+ static int clk_utmi_is_prepared(struct clk_hw *hw)
+ {
+ struct clk_utmi *utmi = to_clk_utmi(hw);
+- struct at91_pmc *pmc = utmi->pmc;
+
+- return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU);
++ return clk_utmi_ready(utmi->regmap);
+ }
+
+ static void clk_utmi_unprepare(struct clk_hw *hw)
+ {
+ struct clk_utmi *utmi = to_clk_utmi(hw);
+- struct at91_pmc *pmc = utmi->pmc;
+- u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN;
+
+- pmc_write(pmc, AT91_CKGR_UCKR, tmp);
++ regmap_update_bits(utmi->regmap, AT91_CKGR_UCKR, AT91_PMC_UPLLEN, 0);
+ }
+
+ static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw,
+@@ -93,7 +100,7 @@ static const struct clk_ops utmi_ops = {
+ };
+
+ static struct clk * __init
+-at91_clk_register_utmi(struct at91_pmc *pmc, unsigned int irq,
++at91_clk_register_utmi(struct regmap *regmap, unsigned int irq,
+ const char *name, const char *parent_name)
+ {
+ int ret;
+@@ -112,7 +119,7 @@ at91_clk_register_utmi(struct at91_pmc *
+ init.flags = CLK_SET_RATE_GATE;
+
+ utmi->hw.init = &init;
+- utmi->pmc = pmc;
++ utmi->regmap = regmap;
+ utmi->irq = irq;
+ init_waitqueue_head(&utmi->wait);
+ irq_set_status_flags(utmi->irq, IRQ_NOAUTOEN);
+@@ -132,13 +139,13 @@ at91_clk_register_utmi(struct at91_pmc *
+ return clk;
+ }
+
+-static void __init
+-of_at91_clk_utmi_setup(struct device_node *np, struct at91_pmc *pmc)
++static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
+ {
+ unsigned int irq;
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
++ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+@@ -148,16 +155,16 @@ of_at91_clk_utmi_setup(struct device_nod
+ if (!irq)
+ return;
+
+- clk = at91_clk_register_utmi(pmc, irq, name, parent_name);
++ regmap = syscon_node_to_regmap(of_get_parent(np));
++ if (IS_ERR(regmap))
++ return;
++
++ clk = at91_clk_register_utmi(regmap, irq, name, parent_name);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ return;
+ }
+-
+-void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np,
+- struct at91_pmc *pmc)
+-{
+- of_at91_clk_utmi_setup(np, pmc);
+-}
++CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
++ of_at91sam9x5_clk_utmi_setup);
+--- a/drivers/clk/at91/pmc.c
++++ b/drivers/clk/at91/pmc.c
+@@ -20,6 +20,7 @@
+ #include <linux/irqdomain.h>
+ #include <linux/of_irq.h>
+ #include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+
+ #include <asm/proc-fns.h>
+
+@@ -70,14 +71,14 @@ static void pmc_irq_mask(struct irq_data
+ {
+ struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+
+- pmc_write(pmc, AT91_PMC_IDR, 1 << d->hwirq);
++ regmap_write(pmc->regmap, AT91_PMC_IDR, 1 << d->hwirq);
+ }
+
+ static void pmc_irq_unmask(struct irq_data *d)
+ {
+ struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+
+- pmc_write(pmc, AT91_PMC_IER, 1 << d->hwirq);
++ regmap_write(pmc->regmap, AT91_PMC_IER, 1 << d->hwirq);
+ }
+
+ static int pmc_irq_set_type(struct irq_data *d, unsigned type)
+@@ -94,15 +95,15 @@ static void pmc_irq_suspend(struct irq_d
+ {
+ struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+
+- pmc->imr = pmc_read(pmc, AT91_PMC_IMR);
+- pmc_write(pmc, AT91_PMC_IDR, pmc->imr);
++ regmap_read(pmc->regmap, AT91_PMC_IMR, &pmc->imr);
++ regmap_write(pmc->regmap, AT91_PMC_IDR, pmc->imr);
+ }
+
+ static void pmc_irq_resume(struct irq_data *d)
+ {
+ struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+
+- pmc_write(pmc, AT91_PMC_IER, pmc->imr);
++ regmap_write(pmc->regmap, AT91_PMC_IER, pmc->imr);
+ }
+
+ static struct irq_chip pmc_irq = {
+@@ -161,10 +162,14 @@ static const struct irq_domain_ops pmc_i
+ static irqreturn_t pmc_irq_handler(int irq, void *data)
+ {
+ struct at91_pmc *pmc = (struct at91_pmc *)data;
++ unsigned int tmpsr, imr;
+ unsigned long sr;
+ int n;
+
+- sr = pmc_read(pmc, AT91_PMC_SR) & pmc_read(pmc, AT91_PMC_IMR);
++ regmap_read(pmc->regmap, AT91_PMC_SR, &tmpsr);
++ regmap_read(pmc->regmap, AT91_PMC_IMR, &imr);
++
++ sr = tmpsr & imr;
+ if (!sr)
+ return IRQ_NONE;
+
+@@ -239,17 +244,15 @@ static struct at91_pmc *__init at91_pmc_
+ if (!pmc)
+ return NULL;
+
+- spin_lock_init(&pmc->lock);
+ pmc->regmap = regmap;
+ pmc->virq = virq;
+ pmc->caps = caps;
+
+ pmc->irqdomain = irq_domain_add_linear(np, 32, &pmc_irq_ops, pmc);
+-
+ if (!pmc->irqdomain)
+ goto out_free_pmc;
+
+- pmc_write(pmc, AT91_PMC_IDR, 0xffffffff);
++ regmap_write(pmc->regmap, AT91_PMC_IDR, 0xffffffff);
+ if (request_irq(pmc->virq, pmc_irq_handler,
+ IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc))
+ goto out_remove_irqdomain;
+@@ -264,137 +267,10 @@ static struct at91_pmc *__init at91_pmc_
+ return NULL;
+ }
+
+-static const struct of_device_id pmc_clk_ids[] __initconst = {
+- /* Slow oscillator */
+- {
+- .compatible = "atmel,at91sam9260-clk-slow",
+- .data = of_at91sam9260_clk_slow_setup,
+- },
+- /* Main clock */
+- {
+- .compatible = "atmel,at91rm9200-clk-main-osc",
+- .data = of_at91rm9200_clk_main_osc_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9x5-clk-main-rc-osc",
+- .data = of_at91sam9x5_clk_main_rc_osc_setup,
+- },
+- {
+- .compatible = "atmel,at91rm9200-clk-main",
+- .data = of_at91rm9200_clk_main_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9x5-clk-main",
+- .data = of_at91sam9x5_clk_main_setup,
+- },
+- /* PLL clocks */
+- {
+- .compatible = "atmel,at91rm9200-clk-pll",
+- .data = of_at91rm9200_clk_pll_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9g45-clk-pll",
+- .data = of_at91sam9g45_clk_pll_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9g20-clk-pllb",
+- .data = of_at91sam9g20_clk_pllb_setup,
+- },
+- {
+- .compatible = "atmel,sama5d3-clk-pll",
+- .data = of_sama5d3_clk_pll_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9x5-clk-plldiv",
+- .data = of_at91sam9x5_clk_plldiv_setup,
+- },
+- /* Master clock */
+- {
+- .compatible = "atmel,at91rm9200-clk-master",
+- .data = of_at91rm9200_clk_master_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9x5-clk-master",
+- .data = of_at91sam9x5_clk_master_setup,
+- },
+- /* System clocks */
+- {
+- .compatible = "atmel,at91rm9200-clk-system",
+- .data = of_at91rm9200_clk_sys_setup,
+- },
+- /* Peripheral clocks */
+- {
+- .compatible = "atmel,at91rm9200-clk-peripheral",
+- .data = of_at91rm9200_clk_periph_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9x5-clk-peripheral",
+- .data = of_at91sam9x5_clk_periph_setup,
+- },
+- /* Programmable clocks */
+- {
+- .compatible = "atmel,at91rm9200-clk-programmable",
+- .data = of_at91rm9200_clk_prog_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9g45-clk-programmable",
+- .data = of_at91sam9g45_clk_prog_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9x5-clk-programmable",
+- .data = of_at91sam9x5_clk_prog_setup,
+- },
+- /* UTMI clock */
+-#if defined(CONFIG_HAVE_AT91_UTMI)
+- {
+- .compatible = "atmel,at91sam9x5-clk-utmi",
+- .data = of_at91sam9x5_clk_utmi_setup,
+- },
+-#endif
+- /* USB clock */
+-#if defined(CONFIG_HAVE_AT91_USB_CLK)
+- {
+- .compatible = "atmel,at91rm9200-clk-usb",
+- .data = of_at91rm9200_clk_usb_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9x5-clk-usb",
+- .data = of_at91sam9x5_clk_usb_setup,
+- },
+- {
+- .compatible = "atmel,at91sam9n12-clk-usb",
+- .data = of_at91sam9n12_clk_usb_setup,
+- },
+-#endif
+- /* SMD clock */
+-#if defined(CONFIG_HAVE_AT91_SMD)
+- {
+- .compatible = "atmel,at91sam9x5-clk-smd",
+- .data = of_at91sam9x5_clk_smd_setup,
+- },
+-#endif
+-#if defined(CONFIG_HAVE_AT91_H32MX)
+- {
+- .compatible = "atmel,sama5d4-clk-h32mx",
+- .data = of_sama5d4_clk_h32mx_setup,
+- },
+-#endif
+-#if defined(CONFIG_HAVE_AT91_GENERATED_CLK)
+- {
+- .compatible = "atmel,sama5d2-clk-generated",
+- .data = of_sama5d2_clk_generated_setup,
+- },
+-#endif
+- { /*sentinel*/ }
+-};
+-
+ static void __init of_at91_pmc_setup(struct device_node *np,
+ const struct at91_pmc_caps *caps)
+ {
+ struct at91_pmc *pmc;
+- struct device_node *childnp;
+- void (*clk_setup)(struct device_node *, struct at91_pmc *);
+- const struct of_device_id *clk_id;
+ void __iomem *regbase = of_iomap(np, 0);
+ struct regmap *regmap;
+ int virq;
+@@ -410,13 +286,6 @@ static void __init of_at91_pmc_setup(str
+ pmc = at91_pmc_init(np, regmap, regbase, virq, caps);
+ if (!pmc)
+ return;
+- for_each_child_of_node(np, childnp) {
+- clk_id = of_match_node(pmc_clk_ids, childnp);
+- if (!clk_id)
+- continue;
+- clk_setup = clk_id->data;
+- clk_setup(childnp, pmc);
+- }
+ }
+
+ static void __init of_at91rm9200_pmc_setup(struct device_node *np)
+--- a/drivers/clk/at91/pmc.h
++++ b/drivers/clk/at91/pmc.h
+@@ -17,6 +17,8 @@
+ #include <linux/regmap.h>
+ #include <linux/spinlock.h>
+
++extern spinlock_t pmc_pcr_lock;
++
+ struct clk_range {
+ unsigned long min;
+ unsigned long max;
+@@ -31,99 +33,12 @@ struct at91_pmc_caps {
+ struct at91_pmc {
+ struct regmap *regmap;
+ int virq;
+- spinlock_t lock;
+ const struct at91_pmc_caps *caps;
+ struct irq_domain *irqdomain;
+ u32 imr;
+ };
+
+-static inline void pmc_lock(struct at91_pmc *pmc)
+-{
+- spin_lock(&pmc->lock);
+-}
+-
+-static inline void pmc_unlock(struct at91_pmc *pmc)
+-{
+- spin_unlock(&pmc->lock);
+-}
+-
+-static inline u32 pmc_read(struct at91_pmc *pmc, int offset)
+-{
+- unsigned int ret = 0;
+-
+- regmap_read(pmc->regmap, offset, &ret);
+-
+- return ret;
+-}
+-
+-static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value)
+-{
+- regmap_write(pmc->regmap, offset, value);
+-}
+-
+ int of_at91_get_clk_range(struct device_node *np, const char *propname,
+ struct clk_range *range);
+
+-void of_at91sam9260_clk_slow_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_at91rm9200_clk_main_osc_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91rm9200_clk_main_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9x5_clk_main_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_at91rm9200_clk_pll_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9g45_clk_pll_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9g20_clk_pllb_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_sama5d3_clk_pll_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9x5_clk_plldiv_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_at91rm9200_clk_master_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9x5_clk_master_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_at91rm9200_clk_sys_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_at91rm9200_clk_periph_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9x5_clk_periph_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_at91rm9200_clk_prog_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9g45_clk_prog_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9x5_clk_prog_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_at91sam9x5_clk_utmi_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_at91rm9200_clk_usb_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9x5_clk_usb_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-void of_at91sam9n12_clk_usb_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_at91sam9x5_clk_smd_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_sama5d4_clk_h32mx_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+-void of_sama5d2_clk_generated_setup(struct device_node *np,
+- struct at91_pmc *pmc);
+-
+ #endif /* __PMC_H_ */
diff --git a/patches/0002-kbuild-Add-option-to-turn-incompatible-pointer-check.patch b/patches/0002-kbuild-Add-option-to-turn-incompatible-pointer-check.patch
new file mode 100644
index 00000000000000..e77f4c506af276
--- /dev/null
+++ b/patches/0002-kbuild-Add-option-to-turn-incompatible-pointer-check.patch
@@ -0,0 +1,52 @@
+From: Daniel Wagner <daniel.wagner@bmw-carit.de>
+Date: Fri, 19 Feb 2016 09:46:38 +0100
+Subject: [PATCH 2/5] kbuild: Add option to turn incompatible pointer check
+ into error
+
+With the introduction of the simple wait API we have two very
+similar APIs in the kernel. For example wake_up() and swake_up()
+is only one character away. Although the compiler will warn
+happily the wrong usage it keeps on going an even links the kernel.
+Thomas and Peter would rather like to see early missuses reported
+as error early on.
+
+In a first attempt we tried to wrap all swait and wait calls
+into a macro which has an compile time type assertion. The result
+was pretty ugly and wasn't able to catch all wrong usages.
+woken_wake_function(), autoremove_wake_function() and wake_bit_function()
+are assigned as function pointers. Wrapping them with a macro around is
+not possible. Prefixing them with '_' was also not a real option
+because there some users in the kernel which do use them as well.
+All in all this attempt looked to intrusive and too ugly.
+
+An alternative is to turn the pointer type check into an error which
+catches wrong type uses. Obviously not only the swait/wait ones. That
+isn't a bad thing either.
+
+Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: linux-rt-users@vger.kernel.org
+Cc: Boqun Feng <boqun.feng@gmail.com>
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Link: http://lkml.kernel.org/r/1455871601-27484-3-git-send-email-wagi@monom.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+---
+ Makefile | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/Makefile
++++ b/Makefile
+@@ -767,6 +767,9 @@ KBUILD_CFLAGS += $(call cc-option,-Wer
+ # Prohibit date/time macros, which would make the build non-deterministic
+ KBUILD_CFLAGS += $(call cc-option,-Werror=date-time)
+
++# enforce correct pointer usage
++KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)
++
+ # use the deterministic mode of AR if available
+ KBUILD_ARFLAGS := $(call ar-option,D)
+
diff --git a/patches/KVM-use-simple-waitqueue-for-vcpu-wq.patch b/patches/0003-KVM-Use-simple-waitqueue-for-vcpu-wq.patch
index b461f6f3bb9e23..09a82350cab45c 100644
--- a/patches/KVM-use-simple-waitqueue-for-vcpu-wq.patch
+++ b/patches/0003-KVM-Use-simple-waitqueue-for-vcpu-wq.patch
@@ -1,10 +1,10 @@
From: Marcelo Tosatti <mtosatti@redhat.com>
-Date: Wed, 8 Apr 2015 20:33:24 -0300
-Subject: KVM: use simple waitqueue for vcpu->wq
+Date: Fri, 19 Feb 2016 09:46:39 +0100
+Subject: [PATCH 3/5] KVM: Use simple waitqueue for vcpu->wq
The problem:
-On -RT, an emulated LAPIC timer instances has the following path:
+On -rt, an emulated LAPIC timer instances has the following path:
1) hard interrupt
2) ksoftirqd is scheduled
@@ -25,24 +25,77 @@ waiter involves locking a sleeping lock, which
is not allowed from hard interrupt context.
cyclictest command line:
-# cyclictest -m -n -q -p99 -l 1000000 -h60 -D 1m
This patch reduces the average latency in my tests from 14us to 11us.
-Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Daniel writes:
+Paolo asked for numbers from kvm-unit-tests/tscdeadline_latency
+benchmark on mainline. The test was run 1000 times on
+tip/sched/core 4.4.0-rc8-01134-g0905f04:
+
+ ./x86-run x86/tscdeadline_latency.flat -cpu host
+
+with idle=poll.
+
+The test seems not to deliver really stable numbers though most of
+them are smaller. Paolo write:
+
+"Anything above ~10000 cycles means that the host went to C1 or
+lower---the number means more or less nothing in that case.
+
+The mean shows an improvement indeed."
+
+Before:
+
+ min max mean std
+count 1000.000000 1000.000000 1000.000000 1000.000000
+mean 5162.596000 2019270.084000 5824.491541 20681.645558
+std 75.431231 622607.723969 89.575700 6492.272062
+min 4466.000000 23928.000000 5537.926500 585.864966
+25% 5163.000000 1613252.750000 5790.132275 16683.745433
+50% 5175.000000 2281919.000000 5834.654000 23151.990026
+75% 5190.000000 2382865.750000 5861.412950 24148.206168
+max 5228.000000 4175158.000000 6254.827300 46481.048691
+
+After
+ min max mean std
+count 1000.000000 1000.00000 1000.000000 1000.000000
+mean 5143.511000 2076886.10300 5813.312474 21207.357565
+std 77.668322 610413.09583 86.541500 6331.915127
+min 4427.000000 25103.00000 5529.756600 559.187707
+25% 5148.000000 1691272.75000 5784.889825 17473.518244
+50% 5160.000000 2308328.50000 5832.025000 23464.837068
+75% 5172.000000 2393037.75000 5853.177675 24223.969976
+max 5222.000000 3922458.00000 6186.720500 42520.379830
+
+[Patch was originaly based on the swait implementation found in the -rt
+ tree. Daniel ported it to mainline's version and gathered the
+ benchmark numbers for tscdeadline_latency test.]
+
+Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: linux-rt-users@vger.kernel.org
+Cc: Boqun Feng <boqun.feng@gmail.com>
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Link: http://lkml.kernel.org/r/1455871601-27484-4-git-send-email-wagi@monom.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/arm/kvm/arm.c | 8 ++++----
arch/arm/kvm/psci.c | 4 ++--
+ arch/mips/kvm/mips.c | 8 ++++----
arch/powerpc/include/asm/kvm_host.h | 4 ++--
arch/powerpc/kvm/book3s_hv.c | 23 +++++++++++------------
arch/s390/include/asm/kvm_host.h | 2 +-
arch/s390/kvm/interrupt.c | 4 ++--
arch/x86/kvm/lapic.c | 6 +++---
- include/linux/kvm_host.h | 4 ++--
+ include/linux/kvm_host.h | 5 +++--
virt/kvm/async_pf.c | 4 ++--
- virt/kvm/kvm_main.c | 16 ++++++++--------
- 10 files changed, 37 insertions(+), 38 deletions(-)
+ virt/kvm/kvm_main.c | 17 ++++++++---------
+ 11 files changed, 42 insertions(+), 43 deletions(-)
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -51,18 +104,18 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kvm_for_each_vcpu(i, vcpu, kvm) {
- wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
-+ struct swait_head *wq = kvm_arch_vcpu_wq(vcpu);
++ struct swait_queue_head *wq = kvm_arch_vcpu_wq(vcpu);
vcpu->arch.pause = false;
- wake_up_interruptible(wq);
-+ swait_wake_interruptible(wq);
++ swake_up(wq);
}
}
static void vcpu_sleep(struct kvm_vcpu *vcpu)
{
- wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
-+ struct swait_head *wq = kvm_arch_vcpu_wq(vcpu);
++ struct swait_queue_head *wq = kvm_arch_vcpu_wq(vcpu);
- wait_event_interruptible(*wq, ((!vcpu->arch.power_off) &&
+ swait_event_interruptible(*wq, ((!vcpu->arch.power_off) &&
@@ -76,7 +129,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
struct kvm *kvm = source_vcpu->kvm;
struct kvm_vcpu *vcpu = NULL;
- wait_queue_head_t *wq;
-+ struct swait_head *wq;
++ struct swait_queue_head *wq;
unsigned long cpu_id;
unsigned long context_id;
phys_addr_t target_pc;
@@ -85,10 +138,34 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
wq = kvm_arch_vcpu_wq(vcpu);
- wake_up_interruptible(wq);
-+ swait_wake_interruptible(wq);
++ swake_up(wq);
return PSCI_RET_SUCCESS;
}
+--- a/arch/mips/kvm/mips.c
++++ b/arch/mips/kvm/mips.c
+@@ -445,8 +445,8 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_
+
+ dvcpu->arch.wait = 0;
+
+- if (waitqueue_active(&dvcpu->wq))
+- wake_up_interruptible(&dvcpu->wq);
++ if (swait_active(&dvcpu->wq))
++ swake_up(&dvcpu->wq);
+
+ return 0;
+ }
+@@ -1174,8 +1174,8 @@ static void kvm_mips_comparecount_func(u
+ kvm_mips_callbacks->queue_timer_int(vcpu);
+
+ vcpu->arch.wait = 0;
+- if (waitqueue_active(&vcpu->wq))
+- wake_up_interruptible(&vcpu->wq);
++ if (swait_active(&vcpu->wq))
++ swake_up(&vcpu->wq);
+ }
+
+ /* low level hrtimer wake routine */
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -286,7 +286,7 @@ struct kvmppc_vcore {
@@ -96,7 +173,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
struct list_head preempt_list;
spinlock_t lock;
- wait_queue_head_t wq;
-+ struct swait_head wq;
++ struct swait_queue_head wq;
spinlock_t stoltb_lock; /* protects stolen_tb and preempt_tb */
u64 stolen_tb;
u64 preempt_tb;
@@ -105,7 +182,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
u32 last_inst;
- wait_queue_head_t *wqp;
-+ struct swait_head *wqp;
++ struct swait_queue_head *wqp;
struct kvmppc_vcore *vcore;
int ret;
int trap;
@@ -116,13 +193,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
{
int cpu;
- wait_queue_head_t *wqp;
-+ struct swait_head *wqp;
++ struct swait_queue_head *wqp;
wqp = kvm_arch_vcpu_wq(vcpu);
- if (waitqueue_active(wqp)) {
- wake_up_interruptible(wqp);
-+ if (swaitqueue_active(wqp)) {
-+ swait_wake_interruptible(wqp);
++ if (swait_active(wqp)) {
++ swake_up(wqp);
++vcpu->stat.halt_wakeup;
}
@@ -132,8 +209,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (vcpu->arch.ceded) {
- if (waitqueue_active(&vcpu->wq)) {
- wake_up_interruptible(&vcpu->wq);
-+ if (swaitqueue_active(&vcpu->wq)) {
-+ swait_wake_interruptible(&vcpu->wq);
++ if (swait_active(&vcpu->wq)) {
++ swake_up(&vcpu->wq);
vcpu->stat.halt_wakeup++;
}
}
@@ -142,7 +219,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
spin_lock_init(&vcore->lock);
spin_lock_init(&vcore->stoltb_lock);
- init_waitqueue_head(&vcore->wq);
-+ init_swait_head(&vcore->wq);
++ init_swait_queue_head(&vcore->wq);
vcore->preempt_tb = TB_NIL;
vcore->lpcr = kvm->arch.lpcr;
vcore->first_vcpuid = core * threads_per_subcore;
@@ -150,12 +227,12 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
{
struct kvm_vcpu *vcpu;
int do_sleep = 1;
-+ DEFINE_SWAITER(wait);
++ DECLARE_SWAITQUEUE(wait);
- DEFINE_WAIT(wait);
-
- prepare_to_wait(&vc->wq, &wait, TASK_INTERRUPTIBLE);
-+ swait_prepare(&vc->wq, &wait, TASK_INTERRUPTIBLE);
++ prepare_to_swait(&vc->wq, &wait, TASK_INTERRUPTIBLE);
/*
* Check one last time for pending exceptions and ceded state after
@@ -164,7 +241,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (!do_sleep) {
- finish_wait(&vc->wq, &wait);
-+ swait_finish(&vc->wq, &wait);
++ finish_swait(&vc->wq, &wait);
return;
}
@@ -173,7 +250,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
spin_unlock(&vc->lock);
schedule();
- finish_wait(&vc->wq, &wait);
-+ swait_finish(&vc->wq, &wait);
++ finish_swait(&vc->wq, &wait);
spin_lock(&vc->lock);
vc->vcore_state = VCORE_INACTIVE;
trace_kvmppc_vcore_blocked(vc, 1);
@@ -182,7 +259,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
trace_kvm_guest_enter(vcpu);
} else if (vc->vcore_state == VCORE_SLEEPING) {
- wake_up(&vc->wq);
-+ swait_wake(&vc->wq);
++ swake_up(&vc->wq);
}
}
@@ -193,7 +270,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
spinlock_t lock;
struct kvm_s390_float_interrupt *float_int;
- wait_queue_head_t *wq;
-+ struct swait_head *wq;
++ struct swait_queue_head *wq;
atomic_t *cpuflags;
DECLARE_BITMAP(sigp_emerg_pending, KVM_MAX_VCPUS);
struct kvm_s390_irq_payload irq;
@@ -204,14 +281,14 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu)
{
- if (waitqueue_active(&vcpu->wq)) {
-+ if (swaitqueue_active(&vcpu->wq)) {
++ if (swait_active(&vcpu->wq)) {
/*
* The vcpu gave up the cpu voluntarily, mark it as a good
* yield-candidate.
*/
vcpu->preempted = true;
- wake_up_interruptible(&vcpu->wq);
-+ swait_wake_interruptible(&vcpu->wq);
++ swake_up(&vcpu->wq);
vcpu->stat.halt_wakeup++;
}
}
@@ -222,7 +299,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
{
struct kvm_vcpu *vcpu = apic->vcpu;
- wait_queue_head_t *q = &vcpu->wq;
-+ struct swait_head *q = &vcpu->wq;
++ struct swait_queue_head *q = &vcpu->wq;
struct kvm_timer *ktimer = &apic->lapic_timer;
if (atomic_read(&apic->lapic_timer.pending))
@@ -232,28 +309,36 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- if (waitqueue_active(q))
- wake_up_interruptible(q);
-+ if (swaitqueue_active(q))
-+ swait_wake_interruptible(q);
++ if (swait_active(q))
++ swake_up(q);
if (apic_lvtt_tscdeadline(apic))
ktimer->expired_tscdeadline = ktimer->tscdeadline;
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
-@@ -243,7 +243,7 @@ struct kvm_vcpu {
+@@ -25,6 +25,7 @@
+ #include <linux/irqflags.h>
+ #include <linux/context_tracking.h>
+ #include <linux/irqbypass.h>
++#include <linux/swait.h>
+ #include <asm/signal.h>
+
+ #include <linux/kvm.h>
+@@ -243,7 +244,7 @@ struct kvm_vcpu {
int fpu_active;
int guest_fpu_loaded, guest_xcr0_loaded;
unsigned char fpu_counter;
- wait_queue_head_t wq;
-+ struct swait_head wq;
++ struct swait_queue_head wq;
struct pid *pid;
int sigset_active;
sigset_t sigset;
-@@ -794,7 +794,7 @@ static inline bool kvm_arch_has_assigned
+@@ -794,7 +795,7 @@ static inline bool kvm_arch_has_assigned
}
#endif
-static inline wait_queue_head_t *kvm_arch_vcpu_wq(struct kvm_vcpu *vcpu)
-+static inline struct swait_head *kvm_arch_vcpu_wq(struct kvm_vcpu *vcpu)
++static inline struct swait_queue_head *kvm_arch_vcpu_wq(struct kvm_vcpu *vcpu)
{
#ifdef __KVM_HAVE_ARCH_WQP
return vcpu->arch.wqp;
@@ -265,70 +350,71 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
smp_mb();
- if (waitqueue_active(&vcpu->wq))
- wake_up_interruptible(&vcpu->wq);
-+ if (swaitqueue_active(&vcpu->wq))
-+ swait_wake_interruptible(&vcpu->wq);
++ if (swait_active(&vcpu->wq))
++ swake_up(&vcpu->wq);
mmput(mm);
kvm_put_kvm(vcpu->kvm);
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
-@@ -227,7 +227,7 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu,
+@@ -226,8 +226,7 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu,
+ vcpu->kvm = kvm;
vcpu->vcpu_id = id;
vcpu->pid = NULL;
- vcpu->halt_poll_ns = 0;
+- vcpu->halt_poll_ns = 0;
- init_waitqueue_head(&vcpu->wq);
-+ init_swait_head(&vcpu->wq);
++ init_swait_queue_head(&vcpu->wq);
kvm_async_pf_vcpu_init(vcpu);
vcpu->pre_pcpu = -1;
-@@ -1999,7 +1999,7 @@ static int kvm_vcpu_check_block(struct k
+@@ -1999,7 +1998,7 @@ static int kvm_vcpu_check_block(struct k
void kvm_vcpu_block(struct kvm_vcpu *vcpu)
{
ktime_t start, cur;
- DEFINE_WAIT(wait);
-+ DEFINE_SWAITER(wait);
++ DECLARE_SWAITQUEUE(wait);
bool waited = false;
u64 block_ns;
-@@ -2024,7 +2024,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcp
+@@ -2024,7 +2023,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcp
kvm_arch_vcpu_blocking(vcpu);
for (;;) {
- prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
-+ swait_prepare(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
++ prepare_to_swait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
if (kvm_vcpu_check_block(vcpu) < 0)
break;
-@@ -2033,7 +2033,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcp
+@@ -2033,7 +2032,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcp
schedule();
}
- finish_wait(&vcpu->wq, &wait);
-+ swait_finish(&vcpu->wq, &wait);
++ finish_swait(&vcpu->wq, &wait);
cur = ktime_get();
kvm_arch_vcpu_unblocking(vcpu);
-@@ -2065,11 +2065,11 @@ void kvm_vcpu_kick(struct kvm_vcpu *vcpu
+@@ -2065,11 +2064,11 @@ void kvm_vcpu_kick(struct kvm_vcpu *vcpu
{
int me;
int cpu = vcpu->cpu;
- wait_queue_head_t *wqp;
-+ struct swait_head *wqp;
++ struct swait_queue_head *wqp;
wqp = kvm_arch_vcpu_wq(vcpu);
- if (waitqueue_active(wqp)) {
- wake_up_interruptible(wqp);
-+ if (swaitqueue_active(wqp)) {
-+ swait_wake_interruptible(wqp);
++ if (swait_active(wqp)) {
++ swake_up(wqp);
++vcpu->stat.halt_wakeup;
}
-@@ -2170,7 +2170,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *m
+@@ -2170,7 +2169,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *m
continue;
if (vcpu == me)
continue;
- if (waitqueue_active(&vcpu->wq) && !kvm_arch_vcpu_runnable(vcpu))
-+ if (swaitqueue_active(&vcpu->wq) && !kvm_arch_vcpu_runnable(vcpu))
++ if (swait_active(&vcpu->wq) && !kvm_arch_vcpu_runnable(vcpu))
continue;
if (!kvm_vcpu_eligible_for_directed_yield(vcpu))
continue;
diff --git a/patches/0003-clk-at91-remove-IRQ-handling-and-use-polling.patch b/patches/0003-clk-at91-remove-IRQ-handling-and-use-polling.patch
new file mode 100644
index 00000000000000..b64bd5cb07ba9e
--- /dev/null
+++ b/patches/0003-clk-at91-remove-IRQ-handling-and-use-polling.patch
@@ -0,0 +1,1033 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Wed, 16 Sep 2015 23:47:39 +0200
+Subject: [PATCH 03/13] clk: at91: remove IRQ handling and use polling
+
+The AT91 clock drivers make use of IRQs to avoid polling when waiting for
+some clocks to be enabled. Unfortunately, this leads to a crash when those
+IRQs are threaded (which happens when using preempt-rt) because they are
+registered before thread creation is possible.
+
+Use polling on those clocks instead to avoid the problem.
+
+Acked-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/clk/at91/clk-main.c | 138 ++++------------------------------------
+ drivers/clk/at91/clk-master.c | 46 +------------
+ drivers/clk/at91/clk-pll.c | 47 +------------
+ drivers/clk/at91/clk-system.c | 56 +---------------
+ drivers/clk/at91/clk-utmi.c | 49 +-------------
+ drivers/clk/at91/pmc.c | 144 ------------------------------------------
+ drivers/clk/at91/pmc.h | 3
+ 7 files changed, 37 insertions(+), 446 deletions(-)
+
+--- a/drivers/clk/at91/clk-main.c
++++ b/drivers/clk/at91/clk-main.c
+@@ -13,15 +13,8 @@
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/delay.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/of_irq.h>
+-#include <linux/io.h>
+-#include <linux/interrupt.h>
+-#include <linux/irq.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+-#include <linux/sched.h>
+-#include <linux/wait.h>
+
+ #include "pmc.h"
+
+@@ -37,8 +30,6 @@
+ struct clk_main_osc {
+ struct clk_hw hw;
+ struct regmap *regmap;
+- unsigned int irq;
+- wait_queue_head_t wait;
+ };
+
+ #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
+@@ -46,8 +37,6 @@ struct clk_main_osc {
+ struct clk_main_rc_osc {
+ struct clk_hw hw;
+ struct regmap *regmap;
+- unsigned int irq;
+- wait_queue_head_t wait;
+ unsigned long frequency;
+ unsigned long accuracy;
+ };
+@@ -64,23 +53,11 @@ struct clk_rm9200_main {
+ struct clk_sam9x5_main {
+ struct clk_hw hw;
+ struct regmap *regmap;
+- unsigned int irq;
+- wait_queue_head_t wait;
+ u8 parent;
+ };
+
+ #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
+
+-static irqreturn_t clk_main_osc_irq_handler(int irq, void *dev_id)
+-{
+- struct clk_main_osc *osc = dev_id;
+-
+- wake_up(&osc->wait);
+- disable_irq_nosync(osc->irq);
+-
+- return IRQ_HANDLED;
+-}
+-
+ static inline bool clk_main_osc_ready(struct regmap *regmap)
+ {
+ unsigned int status;
+@@ -107,11 +84,8 @@ static int clk_main_osc_prepare(struct c
+ regmap_write(regmap, AT91_CKGR_MOR, tmp);
+ }
+
+- while (!clk_main_osc_ready(regmap)) {
+- enable_irq(osc->irq);
+- wait_event(osc->wait,
+- clk_main_osc_ready(regmap));
+- }
++ while (!clk_main_osc_ready(regmap))
++ cpu_relax();
+
+ return 0;
+ }
+@@ -156,17 +130,15 @@ static const struct clk_ops main_osc_ops
+
+ static struct clk * __init
+ at91_clk_register_main_osc(struct regmap *regmap,
+- unsigned int irq,
+ const char *name,
+ const char *parent_name,
+ bool bypass)
+ {
+- int ret;
+ struct clk_main_osc *osc;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+- if (!irq || !name || !parent_name)
++ if (!name || !parent_name)
+ return ERR_PTR(-EINVAL);
+
+ osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+@@ -181,16 +153,6 @@ at91_clk_register_main_osc(struct regmap
+
+ osc->hw.init = &init;
+ osc->regmap = regmap;
+- osc->irq = irq;
+-
+- init_waitqueue_head(&osc->wait);
+- irq_set_status_flags(osc->irq, IRQ_NOAUTOEN);
+- ret = request_irq(osc->irq, clk_main_osc_irq_handler,
+- IRQF_TRIGGER_HIGH, name, osc);
+- if (ret) {
+- kfree(osc);
+- return ERR_PTR(ret);
+- }
+
+ if (bypass)
+ regmap_update_bits(regmap,
+@@ -199,10 +161,8 @@ at91_clk_register_main_osc(struct regmap
+ AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
+
+ clk = clk_register(NULL, &osc->hw);
+- if (IS_ERR(clk)) {
+- free_irq(irq, osc);
++ if (IS_ERR(clk))
+ kfree(osc);
+- }
+
+ return clk;
+ }
+@@ -210,7 +170,6 @@ at91_clk_register_main_osc(struct regmap
+ static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
+ {
+ struct clk *clk;
+- unsigned int irq;
+ const char *name = np->name;
+ const char *parent_name;
+ struct regmap *regmap;
+@@ -224,11 +183,7 @@ static void __init of_at91rm9200_clk_mai
+ if (IS_ERR(regmap))
+ return;
+
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq)
+- return;
+-
+- clk = at91_clk_register_main_osc(regmap, irq, name, parent_name, bypass);
++ clk = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
+ if (IS_ERR(clk))
+ return;
+
+@@ -237,16 +192,6 @@ static void __init of_at91rm9200_clk_mai
+ CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
+ of_at91rm9200_clk_main_osc_setup);
+
+-static irqreturn_t clk_main_rc_osc_irq_handler(int irq, void *dev_id)
+-{
+- struct clk_main_rc_osc *osc = dev_id;
+-
+- wake_up(&osc->wait);
+- disable_irq_nosync(osc->irq);
+-
+- return IRQ_HANDLED;
+-}
+-
+ static bool clk_main_rc_osc_ready(struct regmap *regmap)
+ {
+ unsigned int status;
+@@ -269,11 +214,8 @@ static int clk_main_rc_osc_prepare(struc
+ MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
+ AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
+
+- while (!clk_main_rc_osc_ready(regmap)) {
+- enable_irq(osc->irq);
+- wait_event(osc->wait,
+- clk_main_rc_osc_ready(regmap));
+- }
++ while (!clk_main_rc_osc_ready(regmap))
++ cpu_relax();
+
+ return 0;
+ }
+@@ -331,11 +273,9 @@ static const struct clk_ops main_rc_osc_
+
+ static struct clk * __init
+ at91_clk_register_main_rc_osc(struct regmap *regmap,
+- unsigned int irq,
+ const char *name,
+ u32 frequency, u32 accuracy)
+ {
+- int ret;
+ struct clk_main_rc_osc *osc;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+@@ -355,22 +295,12 @@ at91_clk_register_main_rc_osc(struct reg
+
+ osc->hw.init = &init;
+ osc->regmap = regmap;
+- osc->irq = irq;
+ osc->frequency = frequency;
+ osc->accuracy = accuracy;
+
+- init_waitqueue_head(&osc->wait);
+- irq_set_status_flags(osc->irq, IRQ_NOAUTOEN);
+- ret = request_irq(osc->irq, clk_main_rc_osc_irq_handler,
+- IRQF_TRIGGER_HIGH, name, osc);
+- if (ret)
+- return ERR_PTR(ret);
+-
+ clk = clk_register(NULL, &osc->hw);
+- if (IS_ERR(clk)) {
+- free_irq(irq, osc);
++ if (IS_ERR(clk))
+ kfree(osc);
+- }
+
+ return clk;
+ }
+@@ -378,7 +308,6 @@ at91_clk_register_main_rc_osc(struct reg
+ static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
+ {
+ struct clk *clk;
+- unsigned int irq;
+ u32 frequency = 0;
+ u32 accuracy = 0;
+ const char *name = np->name;
+@@ -388,16 +317,11 @@ static void __init of_at91sam9x5_clk_mai
+ of_property_read_u32(np, "clock-frequency", &frequency);
+ of_property_read_u32(np, "clock-accuracy", &accuracy);
+
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq)
+- return;
+-
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+- clk = at91_clk_register_main_rc_osc(regmap, irq, name, frequency,
+- accuracy);
++ clk = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
+ if (IS_ERR(clk))
+ return;
+
+@@ -529,16 +453,6 @@ static void __init of_at91rm9200_clk_mai
+ CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
+ of_at91rm9200_clk_main_setup);
+
+-static irqreturn_t clk_sam9x5_main_irq_handler(int irq, void *dev_id)
+-{
+- struct clk_sam9x5_main *clkmain = dev_id;
+-
+- wake_up(&clkmain->wait);
+- disable_irq_nosync(clkmain->irq);
+-
+- return IRQ_HANDLED;
+-}
+-
+ static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
+ {
+ unsigned int status;
+@@ -553,11 +467,8 @@ static int clk_sam9x5_main_prepare(struc
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
+ struct regmap *regmap = clkmain->regmap;
+
+- while (!clk_sam9x5_main_ready(regmap)) {
+- enable_irq(clkmain->irq);
+- wait_event(clkmain->wait,
+- clk_sam9x5_main_ready(regmap));
+- }
++ while (!clk_sam9x5_main_ready(regmap))
++ cpu_relax();
+
+ return clk_main_probe_frequency(regmap);
+ }
+@@ -594,11 +505,8 @@ static int clk_sam9x5_main_set_parent(st
+ else if (!index && (tmp & AT91_PMC_MOSCSEL))
+ regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
+
+- while (!clk_sam9x5_main_ready(regmap)) {
+- enable_irq(clkmain->irq);
+- wait_event(clkmain->wait,
+- clk_sam9x5_main_ready(regmap));
+- }
++ while (!clk_sam9x5_main_ready(regmap))
++ cpu_relax();
+
+ return 0;
+ }
+@@ -623,12 +531,10 @@ static const struct clk_ops sam9x5_main_
+
+ static struct clk * __init
+ at91_clk_register_sam9x5_main(struct regmap *regmap,
+- unsigned int irq,
+ const char *name,
+ const char **parent_names,
+ int num_parents)
+ {
+- int ret;
+ struct clk_sam9x5_main *clkmain;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+@@ -652,21 +558,12 @@ at91_clk_register_sam9x5_main(struct reg
+
+ clkmain->hw.init = &init;
+ clkmain->regmap = regmap;
+- clkmain->irq = irq;
+ regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
+ clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0;
+- init_waitqueue_head(&clkmain->wait);
+- irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN);
+- ret = request_irq(clkmain->irq, clk_sam9x5_main_irq_handler,
+- IRQF_TRIGGER_HIGH, name, clkmain);
+- if (ret)
+- return ERR_PTR(ret);
+
+ clk = clk_register(NULL, &clkmain->hw);
+- if (IS_ERR(clk)) {
+- free_irq(clkmain->irq, clkmain);
++ if (IS_ERR(clk))
+ kfree(clkmain);
+- }
+
+ return clk;
+ }
+@@ -676,7 +573,6 @@ static void __init of_at91sam9x5_clk_mai
+ struct clk *clk;
+ const char *parent_names[2];
+ int num_parents;
+- unsigned int irq;
+ const char *name = np->name;
+ struct regmap *regmap;
+
+@@ -691,11 +587,7 @@ static void __init of_at91sam9x5_clk_mai
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq)
+- return;
+-
+- clk = at91_clk_register_sam9x5_main(regmap, irq, name, parent_names,
++ clk = at91_clk_register_sam9x5_main(regmap, name, parent_names,
+ num_parents);
+ if (IS_ERR(clk))
+ return;
+--- a/drivers/clk/at91/clk-master.c
++++ b/drivers/clk/at91/clk-master.c
+@@ -12,13 +12,6 @@
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/of_irq.h>
+-#include <linux/io.h>
+-#include <linux/wait.h>
+-#include <linux/sched.h>
+-#include <linux/interrupt.h>
+-#include <linux/irq.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+@@ -47,22 +40,10 @@ struct clk_master_layout {
+ struct clk_master {
+ struct clk_hw hw;
+ struct regmap *regmap;
+- unsigned int irq;
+- wait_queue_head_t wait;
+ const struct clk_master_layout *layout;
+ const struct clk_master_characteristics *characteristics;
+ };
+
+-static irqreturn_t clk_master_irq_handler(int irq, void *dev_id)
+-{
+- struct clk_master *master = (struct clk_master *)dev_id;
+-
+- wake_up(&master->wait);
+- disable_irq_nosync(master->irq);
+-
+- return IRQ_HANDLED;
+-}
+-
+ static inline bool clk_master_ready(struct regmap *regmap)
+ {
+ unsigned int status;
+@@ -76,11 +57,8 @@ static int clk_master_prepare(struct clk
+ {
+ struct clk_master *master = to_clk_master(hw);
+
+- while (!clk_master_ready(master->regmap)) {
+- enable_irq(master->irq);
+- wait_event(master->wait,
+- clk_master_ready(master->regmap));
+- }
++ while (!clk_master_ready(master->regmap))
++ cpu_relax();
+
+ return 0;
+ }
+@@ -143,13 +121,12 @@ static const struct clk_ops master_ops =
+ };
+
+ static struct clk * __init
+-at91_clk_register_master(struct regmap *regmap, unsigned int irq,
++at91_clk_register_master(struct regmap *regmap,
+ const char *name, int num_parents,
+ const char **parent_names,
+ const struct clk_master_layout *layout,
+ const struct clk_master_characteristics *characteristics)
+ {
+- int ret;
+ struct clk_master *master;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+@@ -171,19 +148,9 @@ at91_clk_register_master(struct regmap *
+ master->layout = layout;
+ master->characteristics = characteristics;
+ master->regmap = regmap;
+- master->irq = irq;
+- init_waitqueue_head(&master->wait);
+- irq_set_status_flags(master->irq, IRQ_NOAUTOEN);
+- ret = request_irq(master->irq, clk_master_irq_handler,
+- IRQF_TRIGGER_HIGH, "clk-master", master);
+- if (ret) {
+- kfree(master);
+- return ERR_PTR(ret);
+- }
+
+ clk = clk_register(NULL, &master->hw);
+ if (IS_ERR(clk)) {
+- free_irq(master->irq, master);
+ kfree(master);
+ }
+
+@@ -233,7 +200,6 @@ of_at91_clk_master_setup(struct device_n
+ {
+ struct clk *clk;
+ int num_parents;
+- unsigned int irq;
+ const char *parent_names[MASTER_SOURCE_MAX];
+ const char *name = np->name;
+ struct clk_master_characteristics *characteristics;
+@@ -255,11 +221,7 @@ of_at91_clk_master_setup(struct device_n
+ if (IS_ERR(regmap))
+ return;
+
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq)
+- goto out_free_characteristics;
+-
+- clk = at91_clk_register_master(regmap, irq, name, num_parents,
++ clk = at91_clk_register_master(regmap, name, num_parents,
+ parent_names, layout,
+ characteristics);
+ if (IS_ERR(clk))
+--- a/drivers/clk/at91/clk-pll.c
++++ b/drivers/clk/at91/clk-pll.c
+@@ -12,14 +12,6 @@
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/of_irq.h>
+-#include <linux/io.h>
+-#include <linux/kernel.h>
+-#include <linux/wait.h>
+-#include <linux/sched.h>
+-#include <linux/interrupt.h>
+-#include <linux/irq.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+@@ -61,8 +53,6 @@ struct clk_pll_layout {
+ struct clk_pll {
+ struct clk_hw hw;
+ struct regmap *regmap;
+- unsigned int irq;
+- wait_queue_head_t wait;
+ u8 id;
+ u8 div;
+ u8 range;
+@@ -71,16 +61,6 @@ struct clk_pll {
+ const struct clk_pll_characteristics *characteristics;
+ };
+
+-static irqreturn_t clk_pll_irq_handler(int irq, void *dev_id)
+-{
+- struct clk_pll *pll = (struct clk_pll *)dev_id;
+-
+- wake_up(&pll->wait);
+- disable_irq_nosync(pll->irq);
+-
+- return IRQ_HANDLED;
+-}
+-
+ static inline bool clk_pll_ready(struct regmap *regmap, int id)
+ {
+ unsigned int status;
+@@ -127,11 +107,8 @@ static int clk_pll_prepare(struct clk_hw
+ (out << PLL_OUT_SHIFT) |
+ ((pll->mul & layout->mul_mask) << layout->mul_shift));
+
+- while (!clk_pll_ready(regmap, pll->id)) {
+- enable_irq(pll->irq);
+- wait_event(pll->wait,
+- clk_pll_ready(regmap, pll->id));
+- }
++ while (!clk_pll_ready(regmap, pll->id))
++ cpu_relax();
+
+ return 0;
+ }
+@@ -320,7 +297,7 @@ static const struct clk_ops pll_ops = {
+ };
+
+ static struct clk * __init
+-at91_clk_register_pll(struct regmap *regmap, unsigned int irq, const char *name,
++at91_clk_register_pll(struct regmap *regmap, const char *name,
+ const char *parent_name, u8 id,
+ const struct clk_pll_layout *layout,
+ const struct clk_pll_characteristics *characteristics)
+@@ -328,7 +305,6 @@ at91_clk_register_pll(struct regmap *reg
+ struct clk_pll *pll;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+- int ret;
+ int offset = PLL_REG(id);
+ unsigned int pllr;
+
+@@ -350,22 +326,12 @@ at91_clk_register_pll(struct regmap *reg
+ pll->layout = layout;
+ pll->characteristics = characteristics;
+ pll->regmap = regmap;
+- pll->irq = irq;
+ regmap_read(regmap, offset, &pllr);
+ pll->div = PLL_DIV(pllr);
+ pll->mul = PLL_MUL(pllr, layout);
+- init_waitqueue_head(&pll->wait);
+- irq_set_status_flags(pll->irq, IRQ_NOAUTOEN);
+- ret = request_irq(pll->irq, clk_pll_irq_handler, IRQF_TRIGGER_HIGH,
+- id ? "clk-pllb" : "clk-plla", pll);
+- if (ret) {
+- kfree(pll);
+- return ERR_PTR(ret);
+- }
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+- free_irq(pll->irq, pll);
+ kfree(pll);
+ }
+
+@@ -499,7 +465,6 @@ of_at91_clk_pll_setup(struct device_node
+ const struct clk_pll_layout *layout)
+ {
+ u32 id;
+- unsigned int irq;
+ struct clk *clk;
+ struct regmap *regmap;
+ const char *parent_name;
+@@ -521,11 +486,7 @@ of_at91_clk_pll_setup(struct device_node
+ if (!characteristics)
+ return;
+
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq)
+- return;
+-
+- clk = at91_clk_register_pll(regmap, irq, name, parent_name, id, layout,
++ clk = at91_clk_register_pll(regmap, name, parent_name, id, layout,
+ characteristics);
+ if (IS_ERR(clk))
+ goto out_free_characteristics;
+--- a/drivers/clk/at91/clk-system.c
++++ b/drivers/clk/at91/clk-system.c
+@@ -12,13 +12,6 @@
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/io.h>
+-#include <linux/irq.h>
+-#include <linux/of_irq.h>
+-#include <linux/interrupt.h>
+-#include <linux/wait.h>
+-#include <linux/sched.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+@@ -32,8 +25,6 @@
+ struct clk_system {
+ struct clk_hw hw;
+ struct regmap *regmap;
+- unsigned int irq;
+- wait_queue_head_t wait;
+ u8 id;
+ };
+
+@@ -41,15 +32,6 @@ static inline int is_pck(int id)
+ {
+ return (id >= 8) && (id <= 15);
+ }
+-static irqreturn_t clk_system_irq_handler(int irq, void *dev_id)
+-{
+- struct clk_system *sys = (struct clk_system *)dev_id;
+-
+- wake_up(&sys->wait);
+- disable_irq_nosync(sys->irq);
+-
+- return IRQ_HANDLED;
+-}
+
+ static inline bool clk_system_ready(struct regmap *regmap, int id)
+ {
+@@ -69,15 +51,9 @@ static int clk_system_prepare(struct clk
+ if (!is_pck(sys->id))
+ return 0;
+
+- while (!clk_system_ready(sys->regmap, sys->id)) {
+- if (sys->irq) {
+- enable_irq(sys->irq);
+- wait_event(sys->wait,
+- clk_system_ready(sys->regmap, sys->id));
+- } else {
+- cpu_relax();
+- }
+- }
++ while (!clk_system_ready(sys->regmap, sys->id))
++ cpu_relax();
++
+ return 0;
+ }
+
+@@ -114,12 +90,11 @@ static const struct clk_ops system_ops =
+
+ static struct clk * __init
+ at91_clk_register_system(struct regmap *regmap, const char *name,
+- const char *parent_name, u8 id, int irq)
++ const char *parent_name, u8 id)
+ {
+ struct clk_system *sys;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+- int ret;
+
+ if (!parent_name || id > SYSTEM_MAX_ID)
+ return ERR_PTR(-EINVAL);
+@@ -137,24 +112,10 @@ at91_clk_register_system(struct regmap *
+ sys->id = id;
+ sys->hw.init = &init;
+ sys->regmap = regmap;
+- sys->irq = irq;
+- if (irq) {
+- init_waitqueue_head(&sys->wait);
+- irq_set_status_flags(sys->irq, IRQ_NOAUTOEN);
+- ret = request_irq(sys->irq, clk_system_irq_handler,
+- IRQF_TRIGGER_HIGH, name, sys);
+- if (ret) {
+- kfree(sys);
+- return ERR_PTR(ret);
+- }
+- }
+
+ clk = clk_register(NULL, &sys->hw);
+- if (IS_ERR(clk)) {
+- if (irq)
+- free_irq(sys->irq, sys);
++ if (IS_ERR(clk))
+ kfree(sys);
+- }
+
+ return clk;
+ }
+@@ -162,7 +123,6 @@ at91_clk_register_system(struct regmap *
+ static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
+ {
+ int num;
+- int irq = 0;
+ u32 id;
+ struct clk *clk;
+ const char *name;
+@@ -185,13 +145,9 @@ static void __init of_at91rm9200_clk_sys
+ if (of_property_read_string(np, "clock-output-names", &name))
+ name = sysclknp->name;
+
+- if (is_pck(id))
+- irq = irq_of_parse_and_map(sysclknp, 0);
+-
+ parent_name = of_clk_get_parent_name(sysclknp, 0);
+
+- clk = at91_clk_register_system(regmap, name, parent_name, id,
+- irq);
++ clk = at91_clk_register_system(regmap, name, parent_name, id);
+ if (IS_ERR(clk))
+ continue;
+
+--- a/drivers/clk/at91/clk-utmi.c
++++ b/drivers/clk/at91/clk-utmi.c
+@@ -11,14 +11,7 @@
+ #include <linux/clk-provider.h>
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+-#include <linux/interrupt.h>
+-#include <linux/irq.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/of_irq.h>
+-#include <linux/io.h>
+-#include <linux/sched.h>
+-#include <linux/wait.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+@@ -29,22 +22,10 @@
+ struct clk_utmi {
+ struct clk_hw hw;
+ struct regmap *regmap;
+- unsigned int irq;
+- wait_queue_head_t wait;
+ };
+
+ #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw)
+
+-static irqreturn_t clk_utmi_irq_handler(int irq, void *dev_id)
+-{
+- struct clk_utmi *utmi = (struct clk_utmi *)dev_id;
+-
+- wake_up(&utmi->wait);
+- disable_irq_nosync(utmi->irq);
+-
+- return IRQ_HANDLED;
+-}
+-
+ static inline bool clk_utmi_ready(struct regmap *regmap)
+ {
+ unsigned int status;
+@@ -62,11 +43,8 @@ static int clk_utmi_prepare(struct clk_h
+
+ regmap_update_bits(utmi->regmap, AT91_CKGR_UCKR, uckr, uckr);
+
+- while (!clk_utmi_ready(utmi->regmap)) {
+- enable_irq(utmi->irq);
+- wait_event(utmi->wait,
+- clk_utmi_ready(utmi->regmap));
+- }
++ while (!clk_utmi_ready(utmi->regmap))
++ cpu_relax();
+
+ return 0;
+ }
+@@ -100,10 +78,9 @@ static const struct clk_ops utmi_ops = {
+ };
+
+ static struct clk * __init
+-at91_clk_register_utmi(struct regmap *regmap, unsigned int irq,
++at91_clk_register_utmi(struct regmap *regmap,
+ const char *name, const char *parent_name)
+ {
+- int ret;
+ struct clk_utmi *utmi;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+@@ -120,28 +97,16 @@ at91_clk_register_utmi(struct regmap *re
+
+ utmi->hw.init = &init;
+ utmi->regmap = regmap;
+- utmi->irq = irq;
+- init_waitqueue_head(&utmi->wait);
+- irq_set_status_flags(utmi->irq, IRQ_NOAUTOEN);
+- ret = request_irq(utmi->irq, clk_utmi_irq_handler,
+- IRQF_TRIGGER_HIGH, "clk-utmi", utmi);
+- if (ret) {
+- kfree(utmi);
+- return ERR_PTR(ret);
+- }
+
+ clk = clk_register(NULL, &utmi->hw);
+- if (IS_ERR(clk)) {
+- free_irq(utmi->irq, utmi);
++ if (IS_ERR(clk))
+ kfree(utmi);
+- }
+
+ return clk;
+ }
+
+ static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
+ {
+- unsigned int irq;
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
+@@ -151,15 +116,11 @@ static void __init of_at91sam9x5_clk_utm
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq)
+- return;
+-
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+- clk = at91_clk_register_utmi(regmap, irq, name, parent_name);
++ clk = at91_clk_register_utmi(regmap, name, parent_name);
+ if (IS_ERR(clk))
+ return;
+
+--- a/drivers/clk/at91/pmc.c
++++ b/drivers/clk/at91/pmc.c
+@@ -13,12 +13,6 @@
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+-#include <linux/io.h>
+-#include <linux/interrupt.h>
+-#include <linux/irq.h>
+-#include <linux/irqchip/chained_irq.h>
+-#include <linux/irqdomain.h>
+-#include <linux/of_irq.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+@@ -67,118 +61,6 @@ int of_at91_get_clk_range(struct device_
+ }
+ EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
+
+-static void pmc_irq_mask(struct irq_data *d)
+-{
+- struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+-
+- regmap_write(pmc->regmap, AT91_PMC_IDR, 1 << d->hwirq);
+-}
+-
+-static void pmc_irq_unmask(struct irq_data *d)
+-{
+- struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+-
+- regmap_write(pmc->regmap, AT91_PMC_IER, 1 << d->hwirq);
+-}
+-
+-static int pmc_irq_set_type(struct irq_data *d, unsigned type)
+-{
+- if (type != IRQ_TYPE_LEVEL_HIGH) {
+- pr_warn("PMC: type not supported (support only IRQ_TYPE_LEVEL_HIGH type)\n");
+- return -EINVAL;
+- }
+-
+- return 0;
+-}
+-
+-static void pmc_irq_suspend(struct irq_data *d)
+-{
+- struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+-
+- regmap_read(pmc->regmap, AT91_PMC_IMR, &pmc->imr);
+- regmap_write(pmc->regmap, AT91_PMC_IDR, pmc->imr);
+-}
+-
+-static void pmc_irq_resume(struct irq_data *d)
+-{
+- struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+-
+- regmap_write(pmc->regmap, AT91_PMC_IER, pmc->imr);
+-}
+-
+-static struct irq_chip pmc_irq = {
+- .name = "PMC",
+- .irq_disable = pmc_irq_mask,
+- .irq_mask = pmc_irq_mask,
+- .irq_unmask = pmc_irq_unmask,
+- .irq_set_type = pmc_irq_set_type,
+- .irq_suspend = pmc_irq_suspend,
+- .irq_resume = pmc_irq_resume,
+-};
+-
+-static struct lock_class_key pmc_lock_class;
+-
+-static int pmc_irq_map(struct irq_domain *h, unsigned int virq,
+- irq_hw_number_t hw)
+-{
+- struct at91_pmc *pmc = h->host_data;
+-
+- irq_set_lockdep_class(virq, &pmc_lock_class);
+-
+- irq_set_chip_and_handler(virq, &pmc_irq,
+- handle_level_irq);
+- irq_set_chip_data(virq, pmc);
+-
+- return 0;
+-}
+-
+-static int pmc_irq_domain_xlate(struct irq_domain *d,
+- struct device_node *ctrlr,
+- const u32 *intspec, unsigned int intsize,
+- irq_hw_number_t *out_hwirq,
+- unsigned int *out_type)
+-{
+- struct at91_pmc *pmc = d->host_data;
+- const struct at91_pmc_caps *caps = pmc->caps;
+-
+- if (WARN_ON(intsize < 1))
+- return -EINVAL;
+-
+- *out_hwirq = intspec[0];
+-
+- if (!(caps->available_irqs & (1 << *out_hwirq)))
+- return -EINVAL;
+-
+- *out_type = IRQ_TYPE_LEVEL_HIGH;
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops pmc_irq_ops = {
+- .map = pmc_irq_map,
+- .xlate = pmc_irq_domain_xlate,
+-};
+-
+-static irqreturn_t pmc_irq_handler(int irq, void *data)
+-{
+- struct at91_pmc *pmc = (struct at91_pmc *)data;
+- unsigned int tmpsr, imr;
+- unsigned long sr;
+- int n;
+-
+- regmap_read(pmc->regmap, AT91_PMC_SR, &tmpsr);
+- regmap_read(pmc->regmap, AT91_PMC_IMR, &imr);
+-
+- sr = tmpsr & imr;
+- if (!sr)
+- return IRQ_NONE;
+-
+- for_each_set_bit(n, &sr, BITS_PER_LONG)
+- generic_handle_irq(irq_find_mapping(pmc->irqdomain, n));
+-
+- return IRQ_HANDLED;
+-}
+-
+ static const struct at91_pmc_caps at91rm9200_caps = {
+ .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB |
+ AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY |
+@@ -230,12 +112,12 @@ static const struct at91_pmc_caps sama5d
+
+ static struct at91_pmc *__init at91_pmc_init(struct device_node *np,
+ struct regmap *regmap,
+- void __iomem *regbase, int virq,
++ void __iomem *regbase,
+ const struct at91_pmc_caps *caps)
+ {
+ struct at91_pmc *pmc;
+
+- if (!regbase || !virq || !caps)
++ if (!regbase || !caps)
+ return NULL;
+
+ at91_pmc_base = regbase;
+@@ -245,26 +127,11 @@ static struct at91_pmc *__init at91_pmc_
+ return NULL;
+
+ pmc->regmap = regmap;
+- pmc->virq = virq;
+ pmc->caps = caps;
+
+- pmc->irqdomain = irq_domain_add_linear(np, 32, &pmc_irq_ops, pmc);
+- if (!pmc->irqdomain)
+- goto out_free_pmc;
+-
+ regmap_write(pmc->regmap, AT91_PMC_IDR, 0xffffffff);
+- if (request_irq(pmc->virq, pmc_irq_handler,
+- IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc))
+- goto out_remove_irqdomain;
+
+ return pmc;
+-
+-out_remove_irqdomain:
+- irq_domain_remove(pmc->irqdomain);
+-out_free_pmc:
+- kfree(pmc);
+-
+- return NULL;
+ }
+
+ static void __init of_at91_pmc_setup(struct device_node *np,
+@@ -273,17 +140,12 @@ static void __init of_at91_pmc_setup(str
+ struct at91_pmc *pmc;
+ void __iomem *regbase = of_iomap(np, 0);
+ struct regmap *regmap;
+- int virq;
+
+ regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(regmap))
+ panic("Could not retrieve syscon regmap");
+
+- virq = irq_of_parse_and_map(np, 0);
+- if (!virq)
+- return;
+-
+- pmc = at91_pmc_init(np, regmap, regbase, virq, caps);
++ pmc = at91_pmc_init(np, regmap, regbase, caps);
+ if (!pmc)
+ return;
+ }
+--- a/drivers/clk/at91/pmc.h
++++ b/drivers/clk/at91/pmc.h
+@@ -32,10 +32,7 @@ struct at91_pmc_caps {
+
+ struct at91_pmc {
+ struct regmap *regmap;
+- int virq;
+ const struct at91_pmc_caps *caps;
+- struct irq_domain *irqdomain;
+- u32 imr;
+ };
+
+ int of_at91_get_clk_range(struct device_node *np, const char *propname,
diff --git a/patches/0004-clk-at91-pmc-merge-at91_pmc_init-in-atmel_pmc_probe.patch b/patches/0004-clk-at91-pmc-merge-at91_pmc_init-in-atmel_pmc_probe.patch
new file mode 100644
index 00000000000000..24f18b5e5d3cc2
--- /dev/null
+++ b/patches/0004-clk-at91-pmc-merge-at91_pmc_init-in-atmel_pmc_probe.patch
@@ -0,0 +1,70 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Wed, 27 Jan 2016 14:59:47 +0100
+Subject: [PATCH 04/13] clk: at91: pmc: merge at91_pmc_init in atmel_pmc_probe
+
+at91_pmc_init() doesn't do much anymore, merge it in atmel_pmc_probe().
+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Acked-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/clk/at91/pmc.c | 34 +++++++++-------------------------
+ 1 file changed, 9 insertions(+), 25 deletions(-)
+
+--- a/drivers/clk/at91/pmc.c
++++ b/drivers/clk/at91/pmc.c
+@@ -110,30 +110,6 @@ static const struct at91_pmc_caps sama5d
+ AT91_PMC_CFDEV,
+ };
+
+-static struct at91_pmc *__init at91_pmc_init(struct device_node *np,
+- struct regmap *regmap,
+- void __iomem *regbase,
+- const struct at91_pmc_caps *caps)
+-{
+- struct at91_pmc *pmc;
+-
+- if (!regbase || !caps)
+- return NULL;
+-
+- at91_pmc_base = regbase;
+-
+- pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
+- if (!pmc)
+- return NULL;
+-
+- pmc->regmap = regmap;
+- pmc->caps = caps;
+-
+- regmap_write(pmc->regmap, AT91_PMC_IDR, 0xffffffff);
+-
+- return pmc;
+-}
+-
+ static void __init of_at91_pmc_setup(struct device_node *np,
+ const struct at91_pmc_caps *caps)
+ {
+@@ -141,13 +117,21 @@ static void __init of_at91_pmc_setup(str
+ void __iomem *regbase = of_iomap(np, 0);
+ struct regmap *regmap;
+
++ at91_pmc_base = regbase;
++
+ regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(regmap))
+ panic("Could not retrieve syscon regmap");
+
+- pmc = at91_pmc_init(np, regmap, regbase, caps);
++ pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
+ if (!pmc)
+ return;
++
++ pmc->regmap = regmap;
++ pmc->caps = caps;
++
++ regmap_write(pmc->regmap, AT91_PMC_IDR, 0xffffffff);
++
+ }
+
+ static void __init of_at91rm9200_pmc_setup(struct device_node *np)
diff --git a/patches/0004-rcu-Do-not-call-rcu_nocb_gp_cleanup-while-holding-rn.patch b/patches/0004-rcu-Do-not-call-rcu_nocb_gp_cleanup-while-holding-rn.patch
new file mode 100644
index 00000000000000..67e5440001be66
--- /dev/null
+++ b/patches/0004-rcu-Do-not-call-rcu_nocb_gp_cleanup-while-holding-rn.patch
@@ -0,0 +1,190 @@
+From: Daniel Wagner <daniel.wagner@bmw-carit.de>
+Date: Fri, 19 Feb 2016 09:46:40 +0100
+Subject: [PATCH 4/5] rcu: Do not call rcu_nocb_gp_cleanup() while holding
+ rnp->lock
+
+rcu_nocb_gp_cleanup() is called while holding rnp->lock. Currently,
+this is okay because the wake_up_all() in rcu_nocb_gp_cleanup() will
+not enable the IRQs. lockdep is happy.
+
+By switching over using swait this is not true anymore. swake_up_all()
+enables the IRQs while processing the waiters. __do_softirq() can now
+run and will eventually call rcu_process_callbacks() which wants to
+grap nrp->lock.
+
+Let's move the rcu_nocb_gp_cleanup() call outside the lock before we
+switch over to swait.
+
+If we would hold the rnp->lock and use swait, lockdep reports
+following:
+
+ =================================
+ [ INFO: inconsistent lock state ]
+ 4.2.0-rc5-00025-g9a73ba0 #136 Not tainted
+ ---------------------------------
+ inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
+ rcu_preempt/8 [HC0[0]:SC0[0]:HE1:SE1] takes:
+ (rcu_node_1){+.?...}, at: [<ffffffff811387c7>] rcu_gp_kthread+0xb97/0xeb0
+ {IN-SOFTIRQ-W} state was registered at:
+ [<ffffffff81109b9f>] __lock_acquire+0xd5f/0x21e0
+ [<ffffffff8110be0f>] lock_acquire+0xdf/0x2b0
+ [<ffffffff81841cc9>] _raw_spin_lock_irqsave+0x59/0xa0
+ [<ffffffff81136991>] rcu_process_callbacks+0x141/0x3c0
+ [<ffffffff810b1a9d>] __do_softirq+0x14d/0x670
+ [<ffffffff810b2214>] irq_exit+0x104/0x110
+ [<ffffffff81844e96>] smp_apic_timer_interrupt+0x46/0x60
+ [<ffffffff81842e70>] apic_timer_interrupt+0x70/0x80
+ [<ffffffff810dba66>] rq_attach_root+0xa6/0x100
+ [<ffffffff810dbc2d>] cpu_attach_domain+0x16d/0x650
+ [<ffffffff810e4b42>] build_sched_domains+0x942/0xb00
+ [<ffffffff821777c2>] sched_init_smp+0x509/0x5c1
+ [<ffffffff821551e3>] kernel_init_freeable+0x172/0x28f
+ [<ffffffff8182cdce>] kernel_init+0xe/0xe0
+ [<ffffffff8184231f>] ret_from_fork+0x3f/0x70
+ irq event stamp: 76
+ hardirqs last enabled at (75): [<ffffffff81841330>] _raw_spin_unlock_irq+0x30/0x60
+ hardirqs last disabled at (76): [<ffffffff8184116f>] _raw_spin_lock_irq+0x1f/0x90
+ softirqs last enabled at (0): [<ffffffff810a8df2>] copy_process.part.26+0x602/0x1cf0
+ softirqs last disabled at (0): [< (null)>] (null)
+ other info that might help us debug this:
+ Possible unsafe locking scenario:
+ CPU0
+ ----
+ lock(rcu_node_1);
+ <Interrupt>
+ lock(rcu_node_1);
+ *** DEADLOCK ***
+ 1 lock held by rcu_preempt/8:
+ #0: (rcu_node_1){+.?...}, at: [<ffffffff811387c7>] rcu_gp_kthread+0xb97/0xeb0
+ stack backtrace:
+ CPU: 0 PID: 8 Comm: rcu_preempt Not tainted 4.2.0-rc5-00025-g9a73ba0 #136
+ Hardware name: Dell Inc. PowerEdge R820/066N7P, BIOS 2.0.20 01/16/2014
+ 0000000000000000 000000006d7e67d8 ffff881fb081fbd8 ffffffff818379e0
+ 0000000000000000 ffff881fb0812a00 ffff881fb081fc38 ffffffff8110813b
+ 0000000000000000 0000000000000001 ffff881f00000001 ffffffff8102fa4f
+ Call Trace:
+ [<ffffffff818379e0>] dump_stack+0x4f/0x7b
+ [<ffffffff8110813b>] print_usage_bug+0x1db/0x1e0
+ [<ffffffff8102fa4f>] ? save_stack_trace+0x2f/0x50
+ [<ffffffff811087ad>] mark_lock+0x66d/0x6e0
+ [<ffffffff81107790>] ? check_usage_forwards+0x150/0x150
+ [<ffffffff81108898>] mark_held_locks+0x78/0xa0
+ [<ffffffff81841330>] ? _raw_spin_unlock_irq+0x30/0x60
+ [<ffffffff81108a28>] trace_hardirqs_on_caller+0x168/0x220
+ [<ffffffff81108aed>] trace_hardirqs_on+0xd/0x10
+ [<ffffffff81841330>] _raw_spin_unlock_irq+0x30/0x60
+ [<ffffffff810fd1c7>] swake_up_all+0xb7/0xe0
+ [<ffffffff811386e1>] rcu_gp_kthread+0xab1/0xeb0
+ [<ffffffff811089bf>] ? trace_hardirqs_on_caller+0xff/0x220
+ [<ffffffff81841341>] ? _raw_spin_unlock_irq+0x41/0x60
+ [<ffffffff81137c30>] ? rcu_barrier+0x20/0x20
+ [<ffffffff810d2014>] kthread+0x104/0x120
+ [<ffffffff81841330>] ? _raw_spin_unlock_irq+0x30/0x60
+ [<ffffffff810d1f10>] ? kthread_create_on_node+0x260/0x260
+ [<ffffffff8184231f>] ret_from_fork+0x3f/0x70
+ [<ffffffff810d1f10>] ? kthread_create_on_node+0x260/0x260
+
+Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: linux-rt-users@vger.kernel.org
+Cc: Boqun Feng <boqun.feng@gmail.com>
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Link: http://lkml.kernel.org/r/1455871601-27484-5-git-send-email-wagi@monom.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+---
+ kernel/rcu/tree.c | 4 +++-
+ kernel/rcu/tree.h | 3 ++-
+ kernel/rcu/tree_plugin.h | 16 +++++++++++++---
+ 3 files changed, 18 insertions(+), 5 deletions(-)
+
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -1590,7 +1590,6 @@ static int rcu_future_gp_cleanup(struct
+ int needmore;
+ struct rcu_data *rdp = this_cpu_ptr(rsp->rda);
+
+- rcu_nocb_gp_cleanup(rsp, rnp);
+ rnp->need_future_gp[c & 0x1] = 0;
+ needmore = rnp->need_future_gp[(c + 1) & 0x1];
+ trace_rcu_future_gp(rnp, rdp, c,
+@@ -1991,6 +1990,7 @@ static void rcu_gp_cleanup(struct rcu_st
+ int nocb = 0;
+ struct rcu_data *rdp;
+ struct rcu_node *rnp = rcu_get_root(rsp);
++ wait_queue_head_t *sq;
+
+ WRITE_ONCE(rsp->gp_activity, jiffies);
+ raw_spin_lock_irq(&rnp->lock);
+@@ -2029,7 +2029,9 @@ static void rcu_gp_cleanup(struct rcu_st
+ needgp = __note_gp_changes(rsp, rnp, rdp) || needgp;
+ /* smp_mb() provided by prior unlock-lock pair. */
+ nocb += rcu_future_gp_cleanup(rsp, rnp);
++ sq = rcu_nocb_gp_get(rnp);
+ raw_spin_unlock_irq(&rnp->lock);
++ rcu_nocb_gp_cleanup(sq);
+ cond_resched_rcu_qs();
+ WRITE_ONCE(rsp->gp_activity, jiffies);
+ rcu_gp_slow(rsp, gp_cleanup_delay);
+--- a/kernel/rcu/tree.h
++++ b/kernel/rcu/tree.h
+@@ -607,7 +607,8 @@ static void zero_cpu_stall_ticks(struct
+ static void increment_cpu_stall_ticks(void);
+ static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu);
+ static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq);
+-static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp);
++static wait_queue_head_t *rcu_nocb_gp_get(struct rcu_node *rnp);
++static void rcu_nocb_gp_cleanup(wait_queue_head_t *sq);
+ static void rcu_init_one_nocb(struct rcu_node *rnp);
+ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
+ bool lazy, unsigned long flags);
+--- a/kernel/rcu/tree_plugin.h
++++ b/kernel/rcu/tree_plugin.h
+@@ -1822,9 +1822,9 @@ early_param("rcu_nocb_poll", parse_rcu_n
+ * Wake up any no-CBs CPUs' kthreads that were waiting on the just-ended
+ * grace period.
+ */
+-static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
++static void rcu_nocb_gp_cleanup(wait_queue_head_t *sq)
+ {
+- wake_up_all(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
++ wake_up_all(sq);
+ }
+
+ /*
+@@ -1840,6 +1840,11 @@ static void rcu_nocb_gp_set(struct rcu_n
+ rnp->need_future_gp[(rnp->completed + 1) & 0x1] += nrq;
+ }
+
++static wait_queue_head_t *rcu_nocb_gp_get(struct rcu_node *rnp)
++{
++ return &rnp->nocb_gp_wq[rnp->completed & 0x1];
++}
++
+ static void rcu_init_one_nocb(struct rcu_node *rnp)
+ {
+ init_waitqueue_head(&rnp->nocb_gp_wq[0]);
+@@ -2514,7 +2519,7 @@ static bool rcu_nocb_cpu_needs_barrier(s
+ return false;
+ }
+
+-static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
++static void rcu_nocb_gp_cleanup(wait_queue_head_t *sq)
+ {
+ }
+
+@@ -2522,6 +2527,11 @@ static void rcu_nocb_gp_set(struct rcu_n
+ {
+ }
+
++static wait_queue_head_t *rcu_nocb_gp_get(struct rcu_node *rnp)
++{
++ return NULL;
++}
++
+ static void rcu_init_one_nocb(struct rcu_node *rnp)
+ {
+ }
diff --git a/patches/0005-clk-at91-pmc-move-pmc-structures-to-C-file.patch b/patches/0005-clk-at91-pmc-move-pmc-structures-to-C-file.patch
new file mode 100644
index 00000000000000..294e4cdd676457
--- /dev/null
+++ b/patches/0005-clk-at91-pmc-move-pmc-structures-to-C-file.patch
@@ -0,0 +1,52 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Thu, 17 Sep 2015 15:26:46 +0200
+Subject: [PATCH 05/13] clk: at91: pmc: move pmc structures to C file
+
+pmc.c is now the only user of struct at91_pmc*, move their definition in
+the C file.
+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Acked-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/clk/at91/pmc.c | 9 +++++++++
+ drivers/clk/at91/pmc.h | 9 ---------
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/clk/at91/pmc.c
++++ b/drivers/clk/at91/pmc.c
+@@ -20,6 +20,15 @@
+
+ #include "pmc.h"
+
++struct at91_pmc_caps {
++ u32 available_irqs;
++};
++
++struct at91_pmc {
++ struct regmap *regmap;
++ const struct at91_pmc_caps *caps;
++};
++
+ void __iomem *at91_pmc_base;
+ EXPORT_SYMBOL_GPL(at91_pmc_base);
+
+--- a/drivers/clk/at91/pmc.h
++++ b/drivers/clk/at91/pmc.h
+@@ -26,15 +26,6 @@ struct clk_range {
+
+ #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,}
+
+-struct at91_pmc_caps {
+- u32 available_irqs;
+-};
+-
+-struct at91_pmc {
+- struct regmap *regmap;
+- const struct at91_pmc_caps *caps;
+-};
+-
+ int of_at91_get_clk_range(struct device_node *np, const char *propname,
+ struct clk_range *range);
+
diff --git a/patches/0005-rcu-Use-simple-wait-queues-where-possible-in-rcutree.patch b/patches/0005-rcu-Use-simple-wait-queues-where-possible-in-rcutree.patch
new file mode 100644
index 00000000000000..cb37231ba67eb9
--- /dev/null
+++ b/patches/0005-rcu-Use-simple-wait-queues-where-possible-in-rcutree.patch
@@ -0,0 +1,310 @@
+From: Paul Gortmaker <paul.gortmaker@windriver.com>
+Date: Fri, 19 Feb 2016 09:46:41 +0100
+Subject: [PATCH 5/5] rcu: Use simple wait queues where possible in rcutree
+
+As of commit dae6e64d2bcfd ("rcu: Introduce proper blocking to no-CBs kthreads
+GP waits") the RCU subsystem started making use of wait queues.
+
+Here we convert all additions of RCU wait queues to use simple wait queues,
+since they don't need the extra overhead of the full wait queue features.
+
+Originally this was done for RT kernels[1], since we would get things like...
+
+ BUG: sleeping function called from invalid context at kernel/rtmutex.c:659
+ in_atomic(): 1, irqs_disabled(): 1, pid: 8, name: rcu_preempt
+ Pid: 8, comm: rcu_preempt Not tainted
+ Call Trace:
+ [<ffffffff8106c8d0>] __might_sleep+0xd0/0xf0
+ [<ffffffff817d77b4>] rt_spin_lock+0x24/0x50
+ [<ffffffff8106fcf6>] __wake_up+0x36/0x70
+ [<ffffffff810c4542>] rcu_gp_kthread+0x4d2/0x680
+ [<ffffffff8105f910>] ? __init_waitqueue_head+0x50/0x50
+ [<ffffffff810c4070>] ? rcu_gp_fqs+0x80/0x80
+ [<ffffffff8105eabb>] kthread+0xdb/0xe0
+ [<ffffffff8106b912>] ? finish_task_switch+0x52/0x100
+ [<ffffffff817e0754>] kernel_thread_helper+0x4/0x10
+ [<ffffffff8105e9e0>] ? __init_kthread_worker+0x60/0x60
+ [<ffffffff817e0750>] ? gs_change+0xb/0xb
+
+...and hence simple wait queues were deployed on RT out of necessity
+(as simple wait uses a raw lock), but mainline might as well take
+advantage of the more streamline support as well.
+
+[1] This is a carry forward of work from v3.10-rt; the original conversion
+was by Thomas on an earlier -rt version, and Sebastian extended it to
+additional post-3.10 added RCU waiters; here I've added a commit log and
+unified the RCU changes into one, and uprev'd it to match mainline RCU.
+
+Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: linux-rt-users@vger.kernel.org
+Cc: Boqun Feng <boqun.feng@gmail.com>
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Link: http://lkml.kernel.org/r/1455871601-27484-6-git-send-email-wagi@monom.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+---
+ kernel/rcu/tree.c | 22 +++++++++++-----------
+ kernel/rcu/tree.h | 13 +++++++------
+ kernel/rcu/tree_plugin.h | 26 +++++++++++++-------------
+ 3 files changed, 31 insertions(+), 30 deletions(-)
+
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -1610,7 +1610,7 @@ static void rcu_gp_kthread_wake(struct r
+ !READ_ONCE(rsp->gp_flags) ||
+ !rsp->gp_kthread)
+ return;
+- wake_up(&rsp->gp_wq);
++ swake_up(&rsp->gp_wq);
+ }
+
+ /*
+@@ -1990,7 +1990,7 @@ static void rcu_gp_cleanup(struct rcu_st
+ int nocb = 0;
+ struct rcu_data *rdp;
+ struct rcu_node *rnp = rcu_get_root(rsp);
+- wait_queue_head_t *sq;
++ struct swait_queue_head *sq;
+
+ WRITE_ONCE(rsp->gp_activity, jiffies);
+ raw_spin_lock_irq(&rnp->lock);
+@@ -2078,7 +2078,7 @@ static int __noreturn rcu_gp_kthread(voi
+ READ_ONCE(rsp->gpnum),
+ TPS("reqwait"));
+ rsp->gp_state = RCU_GP_WAIT_GPS;
+- wait_event_interruptible(rsp->gp_wq,
++ swait_event_interruptible(rsp->gp_wq,
+ READ_ONCE(rsp->gp_flags) &
+ RCU_GP_FLAG_INIT);
+ rsp->gp_state = RCU_GP_DONE_GPS;
+@@ -2108,7 +2108,7 @@ static int __noreturn rcu_gp_kthread(voi
+ READ_ONCE(rsp->gpnum),
+ TPS("fqswait"));
+ rsp->gp_state = RCU_GP_WAIT_FQS;
+- ret = wait_event_interruptible_timeout(rsp->gp_wq,
++ ret = swait_event_interruptible_timeout(rsp->gp_wq,
+ rcu_gp_fqs_check_wake(rsp, &gf), j);
+ rsp->gp_state = RCU_GP_DOING_FQS;
+ /* Locking provides needed memory barriers. */
+@@ -2232,7 +2232,7 @@ static void rcu_report_qs_rsp(struct rcu
+ WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
+ WRITE_ONCE(rsp->gp_flags, READ_ONCE(rsp->gp_flags) | RCU_GP_FLAG_FQS);
+ raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags);
+- rcu_gp_kthread_wake(rsp);
++ swake_up(&rsp->gp_wq); /* Memory barrier implied by swake_up() path. */
+ }
+
+ /*
+@@ -2893,7 +2893,7 @@ static void force_quiescent_state(struct
+ }
+ WRITE_ONCE(rsp->gp_flags, READ_ONCE(rsp->gp_flags) | RCU_GP_FLAG_FQS);
+ raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
+- rcu_gp_kthread_wake(rsp);
++ swake_up(&rsp->gp_wq); /* Memory barrier implied by swake_up() path. */
+ }
+
+ /*
+@@ -3526,7 +3526,7 @@ static void __rcu_report_exp_rnp(struct
+ raw_spin_unlock_irqrestore(&rnp->lock, flags);
+ if (wake) {
+ smp_mb(); /* EGP done before wake_up(). */
+- wake_up(&rsp->expedited_wq);
++ swake_up(&rsp->expedited_wq);
+ }
+ break;
+ }
+@@ -3783,7 +3783,7 @@ static void synchronize_sched_expedited_
+ jiffies_start = jiffies;
+
+ for (;;) {
+- ret = wait_event_interruptible_timeout(
++ ret = swait_event_timeout(
+ rsp->expedited_wq,
+ sync_rcu_preempt_exp_done(rnp_root),
+ jiffies_stall);
+@@ -3791,7 +3791,7 @@ static void synchronize_sched_expedited_
+ return;
+ if (ret < 0) {
+ /* Hit a signal, disable CPU stall warnings. */
+- wait_event(rsp->expedited_wq,
++ swait_event(rsp->expedited_wq,
+ sync_rcu_preempt_exp_done(rnp_root));
+ return;
+ }
+@@ -4457,8 +4457,8 @@ static void __init rcu_init_one(struct r
+ }
+ }
+
+- init_waitqueue_head(&rsp->gp_wq);
+- init_waitqueue_head(&rsp->expedited_wq);
++ init_swait_queue_head(&rsp->gp_wq);
++ init_swait_queue_head(&rsp->expedited_wq);
+ rnp = rsp->level[rcu_num_lvls - 1];
+ for_each_possible_cpu(i) {
+ while (i > rnp->grphi)
+--- a/kernel/rcu/tree.h
++++ b/kernel/rcu/tree.h
+@@ -27,6 +27,7 @@
+ #include <linux/threads.h>
+ #include <linux/cpumask.h>
+ #include <linux/seqlock.h>
++#include <linux/swait.h>
+ #include <linux/stop_machine.h>
+
+ /*
+@@ -241,7 +242,7 @@ struct rcu_node {
+ /* Refused to boost: not sure why, though. */
+ /* This can happen due to race conditions. */
+ #ifdef CONFIG_RCU_NOCB_CPU
+- wait_queue_head_t nocb_gp_wq[2];
++ struct swait_queue_head nocb_gp_wq[2];
+ /* Place for rcu_nocb_kthread() to wait GP. */
+ #endif /* #ifdef CONFIG_RCU_NOCB_CPU */
+ int need_future_gp[2];
+@@ -393,7 +394,7 @@ struct rcu_data {
+ atomic_long_t nocb_q_count_lazy; /* invocation (all stages). */
+ struct rcu_head *nocb_follower_head; /* CBs ready to invoke. */
+ struct rcu_head **nocb_follower_tail;
+- wait_queue_head_t nocb_wq; /* For nocb kthreads to sleep on. */
++ struct swait_queue_head nocb_wq; /* For nocb kthreads to sleep on. */
+ struct task_struct *nocb_kthread;
+ int nocb_defer_wakeup; /* Defer wakeup of nocb_kthread. */
+
+@@ -472,7 +473,7 @@ struct rcu_state {
+ unsigned long gpnum; /* Current gp number. */
+ unsigned long completed; /* # of last completed gp. */
+ struct task_struct *gp_kthread; /* Task for grace periods. */
+- wait_queue_head_t gp_wq; /* Where GP task waits. */
++ struct swait_queue_head gp_wq; /* Where GP task waits. */
+ short gp_flags; /* Commands for GP task. */
+ short gp_state; /* GP kthread sleep state. */
+
+@@ -504,7 +505,7 @@ struct rcu_state {
+ atomic_long_t expedited_workdone3; /* # done by others #3. */
+ atomic_long_t expedited_normal; /* # fallbacks to normal. */
+ atomic_t expedited_need_qs; /* # CPUs left to check in. */
+- wait_queue_head_t expedited_wq; /* Wait for check-ins. */
++ struct swait_queue_head expedited_wq; /* Wait for check-ins. */
+ int ncpus_snap; /* # CPUs seen last time. */
+
+ unsigned long jiffies_force_qs; /* Time at which to invoke */
+@@ -607,8 +608,8 @@ static void zero_cpu_stall_ticks(struct
+ static void increment_cpu_stall_ticks(void);
+ static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu);
+ static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq);
+-static wait_queue_head_t *rcu_nocb_gp_get(struct rcu_node *rnp);
+-static void rcu_nocb_gp_cleanup(wait_queue_head_t *sq);
++static struct swait_queue_head *rcu_nocb_gp_get(struct rcu_node *rnp);
++static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq);
+ static void rcu_init_one_nocb(struct rcu_node *rnp);
+ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
+ bool lazy, unsigned long flags);
+--- a/kernel/rcu/tree_plugin.h
++++ b/kernel/rcu/tree_plugin.h
+@@ -1822,9 +1822,9 @@ early_param("rcu_nocb_poll", parse_rcu_n
+ * Wake up any no-CBs CPUs' kthreads that were waiting on the just-ended
+ * grace period.
+ */
+-static void rcu_nocb_gp_cleanup(wait_queue_head_t *sq)
++static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq)
+ {
+- wake_up_all(sq);
++ swake_up_all(sq);
+ }
+
+ /*
+@@ -1840,15 +1840,15 @@ static void rcu_nocb_gp_set(struct rcu_n
+ rnp->need_future_gp[(rnp->completed + 1) & 0x1] += nrq;
+ }
+
+-static wait_queue_head_t *rcu_nocb_gp_get(struct rcu_node *rnp)
++static struct swait_queue_head *rcu_nocb_gp_get(struct rcu_node *rnp)
+ {
+ return &rnp->nocb_gp_wq[rnp->completed & 0x1];
+ }
+
+ static void rcu_init_one_nocb(struct rcu_node *rnp)
+ {
+- init_waitqueue_head(&rnp->nocb_gp_wq[0]);
+- init_waitqueue_head(&rnp->nocb_gp_wq[1]);
++ init_swait_queue_head(&rnp->nocb_gp_wq[0]);
++ init_swait_queue_head(&rnp->nocb_gp_wq[1]);
+ }
+
+ #ifndef CONFIG_RCU_NOCB_CPU_ALL
+@@ -1873,7 +1873,7 @@ static void wake_nocb_leader(struct rcu_
+ if (READ_ONCE(rdp_leader->nocb_leader_sleep) || force) {
+ /* Prior smp_mb__after_atomic() orders against prior enqueue. */
+ WRITE_ONCE(rdp_leader->nocb_leader_sleep, false);
+- wake_up(&rdp_leader->nocb_wq);
++ swake_up(&rdp_leader->nocb_wq);
+ }
+ }
+
+@@ -2086,7 +2086,7 @@ static void rcu_nocb_wait_gp(struct rcu_
+ */
+ trace_rcu_future_gp(rnp, rdp, c, TPS("StartWait"));
+ for (;;) {
+- wait_event_interruptible(
++ swait_event_interruptible(
+ rnp->nocb_gp_wq[c & 0x1],
+ (d = ULONG_CMP_GE(READ_ONCE(rnp->completed), c)));
+ if (likely(d))
+@@ -2114,7 +2114,7 @@ static void nocb_leader_wait(struct rcu_
+ /* Wait for callbacks to appear. */
+ if (!rcu_nocb_poll) {
+ trace_rcu_nocb_wake(my_rdp->rsp->name, my_rdp->cpu, "Sleep");
+- wait_event_interruptible(my_rdp->nocb_wq,
++ swait_event_interruptible(my_rdp->nocb_wq,
+ !READ_ONCE(my_rdp->nocb_leader_sleep));
+ /* Memory barrier handled by smp_mb() calls below and repoll. */
+ } else if (firsttime) {
+@@ -2189,7 +2189,7 @@ static void nocb_leader_wait(struct rcu_
+ * List was empty, wake up the follower.
+ * Memory barriers supplied by atomic_long_add().
+ */
+- wake_up(&rdp->nocb_wq);
++ swake_up(&rdp->nocb_wq);
+ }
+ }
+
+@@ -2210,7 +2210,7 @@ static void nocb_follower_wait(struct rc
+ if (!rcu_nocb_poll) {
+ trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
+ "FollowerSleep");
+- wait_event_interruptible(rdp->nocb_wq,
++ swait_event_interruptible(rdp->nocb_wq,
+ READ_ONCE(rdp->nocb_follower_head));
+ } else if (firsttime) {
+ /* Don't drown trace log with "Poll"! */
+@@ -2369,7 +2369,7 @@ void __init rcu_init_nohz(void)
+ static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp)
+ {
+ rdp->nocb_tail = &rdp->nocb_head;
+- init_waitqueue_head(&rdp->nocb_wq);
++ init_swait_queue_head(&rdp->nocb_wq);
+ rdp->nocb_follower_tail = &rdp->nocb_follower_head;
+ }
+
+@@ -2519,7 +2519,7 @@ static bool rcu_nocb_cpu_needs_barrier(s
+ return false;
+ }
+
+-static void rcu_nocb_gp_cleanup(wait_queue_head_t *sq)
++static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq)
+ {
+ }
+
+@@ -2527,7 +2527,7 @@ static void rcu_nocb_gp_set(struct rcu_n
+ {
+ }
+
+-static wait_queue_head_t *rcu_nocb_gp_get(struct rcu_node *rnp)
++static struct swait_queue_head *rcu_nocb_gp_get(struct rcu_node *rnp)
+ {
+ return NULL;
+ }
diff --git a/patches/0006-ARM-at91-pm-simply-call-at91_pm_init.patch b/patches/0006-ARM-at91-pm-simply-call-at91_pm_init.patch
new file mode 100644
index 00000000000000..cb5d3f2ae01539
--- /dev/null
+++ b/patches/0006-ARM-at91-pm-simply-call-at91_pm_init.patch
@@ -0,0 +1,41 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Wed, 30 Sep 2015 01:08:33 +0200
+Subject: [PATCH 06/13] ARM: at91: pm: simply call at91_pm_init
+
+at91_pm_init() doesn't return a value, as is the case for its callers,
+simply call it instead of returning its non-existent return value.
+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ arch/arm/mach-at91/pm.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/mach-at91/pm.c
++++ b/arch/arm/mach-at91/pm.c
+@@ -432,7 +432,7 @@ void __init at91sam9260_pm_init(void)
+ 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();
+ }
+
+ void __init at91sam9g45_pm_init(void)
+@@ -440,7 +440,7 @@ void __init at91sam9g45_pm_init(void)
+ 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();
+ }
+
+ void __init at91sam9x5_pm_init(void)
+@@ -448,5 +448,5 @@ void __init at91sam9x5_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;
+- return at91_pm_init();
++ at91_pm_init();
+ }
diff --git a/patches/0007-ARM-at91-pm-find-and-remap-the-pmc.patch b/patches/0007-ARM-at91-pm-find-and-remap-the-pmc.patch
new file mode 100644
index 00000000000000..5564ca952fb2f9
--- /dev/null
+++ b/patches/0007-ARM-at91-pm-find-and-remap-the-pmc.patch
@@ -0,0 +1,90 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Wed, 30 Sep 2015 01:31:34 +0200
+Subject: [PATCH 07/13] ARM: at91: pm: find and remap the pmc
+
+To avoid relying on at91_pmc_read(), find the pmc node and remap it
+locally.
+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ arch/arm/mach-at91/pm.c | 33 +++++++++++++++++++++++++++------
+ 1 file changed, 27 insertions(+), 6 deletions(-)
+
+--- a/arch/arm/mach-at91/pm.c
++++ b/arch/arm/mach-at91/pm.c
+@@ -35,6 +35,8 @@
+ #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
+@@ -87,7 +89,7 @@ static int at91_pm_verify_clocks(void)
+ 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) {
+@@ -101,8 +103,7 @@ static int at91_pm_verify_clocks(void)
+
+ 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;
+@@ -145,8 +146,8 @@ static void at91_pm_suspend(suspend_stat
+ 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();
+ }
+@@ -399,13 +400,33 @@ static void __init at91_pm_sram_init(voi
+ &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
+ }
+
++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)
+ {
+- 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;
++ }
++
++ at91_pm_sram_init();
++
+ if (at91_suspend_sram_fn)
+ suspend_set_ops(&at91_pm_ops);
+ else
diff --git a/patches/0008-ARM-at91-pm-move-idle-functions-to-pm.c.patch b/patches/0008-ARM-at91-pm-move-idle-functions-to-pm.c.patch
new file mode 100644
index 00000000000000..1d016641f0d6d7
--- /dev/null
+++ b/patches/0008-ARM-at91-pm-move-idle-functions-to-pm.c.patch
@@ -0,0 +1,201 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Wed, 30 Sep 2015 01:58:40 +0200
+Subject: [PATCH 08/13] ARM: at91: pm: move idle functions to pm.c
+
+Avoid using code from clk/at91 for PM.
+This also has the bonus effect of setting arm_pm_idle for sama5 platforms.
+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ arch/arm/mach-at91/at91rm9200.c | 2 --
+ arch/arm/mach-at91/at91sam9.c | 2 --
+ arch/arm/mach-at91/generic.h | 6 ++----
+ arch/arm/mach-at91/pm.c | 37 ++++++++++++++++++++++++++++++++-----
+ arch/arm/mach-at91/sama5.c | 2 +-
+ drivers/clk/at91/pmc.c | 15 ---------------
+ 6 files changed, 35 insertions(+), 29 deletions(-)
+
+--- a/arch/arm/mach-at91/at91rm9200.c
++++ b/arch/arm/mach-at91/at91rm9200.c
+@@ -12,7 +12,6 @@
+ #include <linux/of_platform.h>
+
+ #include <asm/mach/arch.h>
+-#include <asm/system_misc.h>
+
+ #include "generic.h"
+ #include "soc.h"
+@@ -33,7 +32,6 @@ static void __init at91rm9200_dt_device_
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
+
+- arm_pm_idle = at91rm9200_idle;
+ at91rm9200_pm_init();
+ }
+
+--- a/arch/arm/mach-at91/at91sam9.c
++++ b/arch/arm/mach-at91/at91sam9.c
+@@ -62,8 +62,6 @@ static void __init at91sam9_common_init(
+ 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)
+--- a/arch/arm/mach-at91/generic.h
++++ b/arch/arm/mach-at91/generic.h
+@@ -18,20 +18,18 @@
+ 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 */
+--- a/arch/arm/mach-at91/pm.c
++++ b/arch/arm/mach-at91/pm.c
+@@ -31,6 +31,7 @@
+ #include <asm/mach/irq.h>
+ #include <asm/fncpy.h>
+ #include <asm/cacheflush.h>
++#include <asm/system_misc.h>
+
+ #include "generic.h"
+ #include "pm.h"
+@@ -354,6 +355,21 @@ static __init void at91_dt_ramc(void)
+ 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;
+@@ -411,7 +427,7 @@ static const struct of_device_id atmel_p
+ { /* sentinel */ },
+ };
+
+-static void __init at91_pm_init(void)
++static void __init at91_pm_init(void (*pm_idle)(void))
+ {
+ struct device_node *pmc_np;
+
+@@ -425,6 +441,9 @@ static void __init at91_pm_init(void)
+ return;
+ }
+
++ if (pm_idle)
++ arm_pm_idle = pm_idle;
++
+ at91_pm_sram_init();
+
+ if (at91_suspend_sram_fn)
+@@ -445,7 +464,7 @@ void __init at91rm9200_pm_init(void)
+ 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)
+@@ -453,7 +472,7 @@ void __init at91sam9260_pm_init(void)
+ at91_dt_ramc();
+ at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+- at91_pm_init();
++ at91_pm_init(at91sam9_idle);
+ }
+
+ void __init at91sam9g45_pm_init(void)
+@@ -461,7 +480,7 @@ void __init at91sam9g45_pm_init(void)
+ at91_dt_ramc();
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
+ at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+- at91_pm_init();
++ at91_pm_init(at91sam9_idle);
+ }
+
+ void __init at91sam9x5_pm_init(void)
+@@ -469,5 +488,13 @@ void __init at91sam9x5_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();
++ 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);
+ }
+--- a/arch/arm/mach-at91/sama5.c
++++ b/arch/arm/mach-at91/sama5.c
+@@ -51,7 +51,7 @@ static void __init sama5_dt_device_init(
+ 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 *const sama5_dt_board_compat[] __initconst = {
+--- a/drivers/clk/at91/pmc.c
++++ b/drivers/clk/at91/pmc.c
+@@ -32,21 +32,6 @@ struct at91_pmc {
+ void __iomem *at91_pmc_base;
+ EXPORT_SYMBOL_GPL(at91_pmc_base);
+
+-void at91rm9200_idle(void)
+-{
+- /*
+- * Disable the processor clock. The processor will be automatically
+- * re-enabled by an interrupt or by a reset.
+- */
+- at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+-}
+-
+-void at91sam9_idle(void)
+-{
+- at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+- cpu_do_idle();
+-}
+-
+ int of_at91_get_clk_range(struct device_node *np, const char *propname,
+ struct clk_range *range)
+ {
diff --git a/patches/0009-ARM-at91-remove-useless-includes-and-function-protot.patch b/patches/0009-ARM-at91-remove-useless-includes-and-function-protot.patch
new file mode 100644
index 00000000000000..4fac07bd3bfc5c
--- /dev/null
+++ b/patches/0009-ARM-at91-remove-useless-includes-and-function-protot.patch
@@ -0,0 +1,30 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Wed, 30 Sep 2015 02:01:20 +0200
+Subject: [PATCH 09/13] ARM: at91: remove useless includes and function
+ prototypes
+
+Remove leftover from the previous cleanup
+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ arch/arm/mach-at91/generic.h | 7 -------
+ 1 file changed, 7 deletions(-)
+
+--- a/arch/arm/mach-at91/generic.h
++++ b/arch/arm/mach-at91/generic.h
+@@ -11,13 +11,6 @@
+ #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);
+-
+ #ifdef CONFIG_PM
+ extern void __init at91rm9200_pm_init(void);
+ extern void __init at91sam9260_pm_init(void);
diff --git a/patches/0010-usb-gadget-atmel-access-the-PMC-using-regmap.patch b/patches/0010-usb-gadget-atmel-access-the-PMC-using-regmap.patch
new file mode 100644
index 00000000000000..379a98ba87f968
--- /dev/null
+++ b/patches/0010-usb-gadget-atmel-access-the-PMC-using-regmap.patch
@@ -0,0 +1,75 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Wed, 30 Sep 2015 12:57:10 +0200
+Subject: [PATCH 10/13] usb: gadget: atmel: access the PMC using regmap
+
+Use regmap to access the PMC to avoid using at91_pmc_read and
+at91_pmc_write.
+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/usb/gadget/udc/atmel_usba_udc.c | 20 ++++++++++----------
+ drivers/usb/gadget/udc/atmel_usba_udc.h | 2 ++
+ 2 files changed, 12 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/gadget/udc/atmel_usba_udc.c
++++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
+@@ -17,7 +17,9 @@
+ #include <linux/device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/list.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/platform_device.h>
++#include <linux/regmap.h>
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/gadget.h>
+ #include <linux/usb/atmel_usba_udc.h>
+@@ -1888,20 +1890,15 @@ static int atmel_usba_stop(struct usb_ga
+ #ifdef CONFIG_OF
+ static void at91sam9rl_toggle_bias(struct usba_udc *udc, int is_on)
+ {
+- unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
+-
+- if (is_on)
+- at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
+- else
+- at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
++ regmap_update_bits(udc->pmc, AT91_CKGR_UCKR, AT91_PMC_BIASEN,
++ is_on ? AT91_PMC_BIASEN : 0);
+ }
+
+ static void at91sam9g45_pulse_bias(struct usba_udc *udc)
+ {
+- unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
+-
+- at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
+- at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
++ regmap_update_bits(udc->pmc, AT91_CKGR_UCKR, AT91_PMC_BIASEN, 0);
++ regmap_update_bits(udc->pmc, AT91_CKGR_UCKR, AT91_PMC_BIASEN,
++ AT91_PMC_BIASEN);
+ }
+
+ static const struct usba_udc_errata at91sam9rl_errata = {
+@@ -1938,6 +1935,9 @@ static struct usba_ep * atmel_udc_of_ini
+ return ERR_PTR(-EINVAL);
+
+ udc->errata = match->data;
++ udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9g45-pmc");
++ if (udc->errata && IS_ERR(udc->pmc))
++ return ERR_CAST(udc->pmc);
+
+ udc->num_ep = 0;
+
+--- a/drivers/usb/gadget/udc/atmel_usba_udc.h
++++ b/drivers/usb/gadget/udc/atmel_usba_udc.h
+@@ -354,6 +354,8 @@ struct usba_udc {
+ struct dentry *debugfs_root;
+ struct dentry *debugfs_regs;
+ #endif
++
++ struct regmap *pmc;
+ };
+
+ static inline struct usba_ep *to_usba_ep(struct usb_ep *ep)
diff --git a/patches/0011-clk-at91-pmc-drop-at91_pmc_base.patch b/patches/0011-clk-at91-pmc-drop-at91_pmc_base.patch
new file mode 100644
index 00000000000000..39addf9379a132
--- /dev/null
+++ b/patches/0011-clk-at91-pmc-drop-at91_pmc_base.patch
@@ -0,0 +1,69 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Wed, 30 Sep 2015 13:02:01 +0200
+Subject: [PATCH 11/13] clk: at91: pmc: drop at91_pmc_base
+
+at91_pmc_base is not used anymore, remove it along with at91_pmc_read and
+at91_pmc_write.
+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Acked-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/clk/at91/pmc.c | 7 -------
+ include/linux/clk/at91_pmc.h | 12 ------------
+ 2 files changed, 19 deletions(-)
+
+--- a/drivers/clk/at91/pmc.c
++++ b/drivers/clk/at91/pmc.c
+@@ -12,7 +12,6 @@
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+@@ -29,9 +28,6 @@ struct at91_pmc {
+ const struct at91_pmc_caps *caps;
+ };
+
+-void __iomem *at91_pmc_base;
+-EXPORT_SYMBOL_GPL(at91_pmc_base);
+-
+ int of_at91_get_clk_range(struct device_node *np, const char *propname,
+ struct clk_range *range)
+ {
+@@ -108,11 +104,8 @@ static void __init of_at91_pmc_setup(str
+ const struct at91_pmc_caps *caps)
+ {
+ struct at91_pmc *pmc;
+- void __iomem *regbase = of_iomap(np, 0);
+ struct regmap *regmap;
+
+- at91_pmc_base = regbase;
+-
+ regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(regmap))
+ panic("Could not retrieve syscon regmap");
+--- a/include/linux/clk/at91_pmc.h
++++ b/include/linux/clk/at91_pmc.h
+@@ -16,18 +16,6 @@
+ #ifndef AT91_PMC_H
+ #define AT91_PMC_H
+
+-#ifndef __ASSEMBLY__
+-extern void __iomem *at91_pmc_base;
+-
+-#define at91_pmc_read(field) \
+- readl_relaxed(at91_pmc_base + field)
+-
+-#define at91_pmc_write(field, value) \
+- writel_relaxed(value, at91_pmc_base + field)
+-#else
+-.extern at91_pmc_base
+-#endif
+-
+ #define AT91_PMC_SCER 0x00 /* System Clock Enable Register */
+ #define AT91_PMC_SCDR 0x04 /* System Clock Disable Register */
+
diff --git a/patches/0012-clk-at91-pmc-remove-useless-capacities-handling.patch b/patches/0012-clk-at91-pmc-remove-useless-capacities-handling.patch
new file mode 100644
index 00000000000000..b54c5bf6fdb5b7
--- /dev/null
+++ b/patches/0012-clk-at91-pmc-remove-useless-capacities-handling.patch
@@ -0,0 +1,155 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Wed, 27 Jan 2016 15:05:55 +0100
+Subject: [PATCH 12/13] clk: at91: pmc: remove useless capacities handling
+
+Capacities only handles interrupts and they are not use anymore. Remove the
+whole initialisation.
+
+Acked-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/clk/at91/pmc.c | 128 -------------------------------------------------
+ 1 file changed, 128 deletions(-)
+
+--- a/drivers/clk/at91/pmc.c
++++ b/drivers/clk/at91/pmc.c
+@@ -19,15 +19,6 @@
+
+ #include "pmc.h"
+
+-struct at91_pmc_caps {
+- u32 available_irqs;
+-};
+-
+-struct at91_pmc {
+- struct regmap *regmap;
+- const struct at91_pmc_caps *caps;
+-};
+-
+ int of_at91_get_clk_range(struct device_node *np, const char *propname,
+ struct clk_range *range)
+ {
+@@ -50,122 +41,3 @@ int of_at91_get_clk_range(struct device_
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
+-
+-static const struct at91_pmc_caps at91rm9200_caps = {
+- .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB |
+- AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY |
+- AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY |
+- AT91_PMC_PCK3RDY,
+-};
+-
+-static const struct at91_pmc_caps at91sam9260_caps = {
+- .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB |
+- AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY |
+- AT91_PMC_PCK1RDY,
+-};
+-
+-static const struct at91_pmc_caps at91sam9g45_caps = {
+- .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
+- AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
+- AT91_PMC_PCK1RDY,
+-};
+-
+-static const struct at91_pmc_caps at91sam9n12_caps = {
+- .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB |
+- AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY |
+- AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS |
+- AT91_PMC_MOSCRCS | AT91_PMC_CFDEV,
+-};
+-
+-static const struct at91_pmc_caps at91sam9x5_caps = {
+- .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
+- AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
+- AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS |
+- AT91_PMC_MOSCRCS | AT91_PMC_CFDEV,
+-};
+-
+-static const struct at91_pmc_caps sama5d2_caps = {
+- .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
+- AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
+- AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY |
+- AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS |
+- AT91_PMC_CFDEV | AT91_PMC_GCKRDY,
+-};
+-
+-static const struct at91_pmc_caps sama5d3_caps = {
+- .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
+- AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
+- AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY |
+- AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS |
+- AT91_PMC_CFDEV,
+-};
+-
+-static void __init of_at91_pmc_setup(struct device_node *np,
+- const struct at91_pmc_caps *caps)
+-{
+- struct at91_pmc *pmc;
+- struct regmap *regmap;
+-
+- regmap = syscon_node_to_regmap(np);
+- if (IS_ERR(regmap))
+- panic("Could not retrieve syscon regmap");
+-
+- pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
+- if (!pmc)
+- return;
+-
+- pmc->regmap = regmap;
+- pmc->caps = caps;
+-
+- regmap_write(pmc->regmap, AT91_PMC_IDR, 0xffffffff);
+-
+-}
+-
+-static void __init of_at91rm9200_pmc_setup(struct device_node *np)
+-{
+- of_at91_pmc_setup(np, &at91rm9200_caps);
+-}
+-CLK_OF_DECLARE(at91rm9200_clk_pmc, "atmel,at91rm9200-pmc",
+- of_at91rm9200_pmc_setup);
+-
+-static void __init of_at91sam9260_pmc_setup(struct device_node *np)
+-{
+- of_at91_pmc_setup(np, &at91sam9260_caps);
+-}
+-CLK_OF_DECLARE(at91sam9260_clk_pmc, "atmel,at91sam9260-pmc",
+- of_at91sam9260_pmc_setup);
+-
+-static void __init of_at91sam9g45_pmc_setup(struct device_node *np)
+-{
+- of_at91_pmc_setup(np, &at91sam9g45_caps);
+-}
+-CLK_OF_DECLARE(at91sam9g45_clk_pmc, "atmel,at91sam9g45-pmc",
+- of_at91sam9g45_pmc_setup);
+-
+-static void __init of_at91sam9n12_pmc_setup(struct device_node *np)
+-{
+- of_at91_pmc_setup(np, &at91sam9n12_caps);
+-}
+-CLK_OF_DECLARE(at91sam9n12_clk_pmc, "atmel,at91sam9n12-pmc",
+- of_at91sam9n12_pmc_setup);
+-
+-static void __init of_at91sam9x5_pmc_setup(struct device_node *np)
+-{
+- of_at91_pmc_setup(np, &at91sam9x5_caps);
+-}
+-CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc",
+- of_at91sam9x5_pmc_setup);
+-
+-static void __init of_sama5d2_pmc_setup(struct device_node *np)
+-{
+- of_at91_pmc_setup(np, &sama5d2_caps);
+-}
+-CLK_OF_DECLARE(sama5d2_clk_pmc, "atmel,sama5d2-pmc",
+- of_sama5d2_pmc_setup);
+-
+-static void __init of_sama5d3_pmc_setup(struct device_node *np)
+-{
+- of_at91_pmc_setup(np, &sama5d3_caps);
+-}
+-CLK_OF_DECLARE(sama5d3_clk_pmc, "atmel,sama5d3-pmc",
+- of_sama5d3_pmc_setup);
diff --git a/patches/0013-clk-at91-remove-useless-includes.patch b/patches/0013-clk-at91-remove-useless-includes.patch
new file mode 100644
index 00000000000000..4329c9e237d4a9
--- /dev/null
+++ b/patches/0013-clk-at91-remove-useless-includes.patch
@@ -0,0 +1,129 @@
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Wed, 27 Jan 2016 15:17:37 +0100
+Subject: [PATCH 13/13] clk: at91: remove useless includes
+
+Over time, some includes were copy pasted from other clocks drivers but are
+not necessary.
+
+Acked-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/clk/at91/clk-generated.c | 2 --
+ drivers/clk/at91/clk-h32mx.c | 8 --------
+ drivers/clk/at91/clk-peripheral.c | 2 --
+ drivers/clk/at91/clk-plldiv.c | 2 --
+ drivers/clk/at91/clk-programmable.c | 4 ----
+ drivers/clk/at91/clk-slow.c | 8 --------
+ drivers/clk/at91/clk-smd.c | 2 --
+ drivers/clk/at91/clk-usb.c | 2 --
+ 8 files changed, 30 deletions(-)
+
+--- a/drivers/clk/at91/clk-generated.c
++++ b/drivers/clk/at91/clk-generated.c
+@@ -15,8 +15,6 @@
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/io.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+--- a/drivers/clk/at91/clk-h32mx.c
++++ b/drivers/clk/at91/clk-h32mx.c
+@@ -15,15 +15,7 @@
+ #include <linux/clk-provider.h>
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+-#include <linux/delay.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/of_irq.h>
+-#include <linux/io.h>
+-#include <linux/interrupt.h>
+-#include <linux/irq.h>
+-#include <linux/sched.h>
+-#include <linux/wait.h>
+ #include <linux/regmap.h>
+ #include <linux/mfd/syscon.h>
+
+--- a/drivers/clk/at91/clk-peripheral.c
++++ b/drivers/clk/at91/clk-peripheral.c
+@@ -12,8 +12,6 @@
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/io.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+--- a/drivers/clk/at91/clk-plldiv.c
++++ b/drivers/clk/at91/clk-plldiv.c
+@@ -12,8 +12,6 @@
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/io.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+--- a/drivers/clk/at91/clk-programmable.c
++++ b/drivers/clk/at91/clk-programmable.c
+@@ -12,10 +12,6 @@
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/io.h>
+-#include <linux/wait.h>
+-#include <linux/sched.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+--- a/drivers/clk/at91/clk-slow.c
++++ b/drivers/clk/at91/clk-slow.c
+@@ -13,19 +13,11 @@
+ #include <linux/clk.h>
+ #include <linux/clk-provider.h>
+ #include <linux/clkdev.h>
+-#include <linux/slab.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/delay.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/of_irq.h>
+-#include <linux/io.h>
+-#include <linux/interrupt.h>
+-#include <linux/irq.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+-#include <linux/sched.h>
+-#include <linux/wait.h>
+
+ #include "pmc.h"
+ #include "sckc.h"
+--- a/drivers/clk/at91/clk-smd.c
++++ b/drivers/clk/at91/clk-smd.c
+@@ -12,8 +12,6 @@
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/io.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
+--- a/drivers/clk/at91/clk-usb.c
++++ b/drivers/clk/at91/clk-usb.c
+@@ -12,8 +12,6 @@
+ #include <linux/clkdev.h>
+ #include <linux/clk/at91_pmc.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/io.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+
diff --git a/patches/KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch b/patches/KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch
index 0ceb93625b547e..ab153a020324a7 100644
--- a/patches/KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch
+++ b/patches/KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch
@@ -1,8 +1,6 @@
-From bdf6fc2d467f0db2122b1010106542dbc7a8398c Mon Sep 17 00:00:00 2001
From: Josh Cartwright <joshc@ni.com>
Date: Thu, 11 Feb 2016 11:54:01 -0600
-Subject: [PATCH 2/2] KVM: arm/arm64: downgrade preempt_disable()d region to
- migrate_disable()
+Subject: KVM: arm/arm64: downgrade preempt_disable()d region to migrate_disable()
kvm_arch_vcpu_ioctl_run() disables the use of preemption when updating
the vgic and timer states to prevent the calling task from migrating to
diff --git a/patches/at91_dont_enable_disable_clock.patch b/patches/at91_dont_enable_disable_clock.patch
new file mode 100644
index 00000000000000..c098bbdd782201
--- /dev/null
+++ b/patches/at91_dont_enable_disable_clock.patch
@@ -0,0 +1,91 @@
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 09 Mar 2016 10:51:06 +0100
+Subject: arm: at91: do not disable/enable clocks in a row
+
+Currently the driver will disable the clock and enable it one line later
+if it is switching from periodic mode into one shot.
+This can be avoided and causes a needless warning on -RT.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/clocksource/tcb_clksrc.c | 33 +++++++++++++++++++++++++++++----
+ 1 file changed, 29 insertions(+), 4 deletions(-)
+
+--- a/drivers/clocksource/tcb_clksrc.c
++++ b/drivers/clocksource/tcb_clksrc.c
+@@ -74,6 +74,7 @@ static struct clocksource clksrc = {
+ struct tc_clkevt_device {
+ struct clock_event_device clkevt;
+ struct clk *clk;
++ bool clk_enabled;
+ void __iomem *regs;
+ };
+
+@@ -91,6 +92,24 @@ static struct tc_clkevt_device *to_tc_cl
+ */
+ static u32 timer_clock;
+
++static void tc_clk_disable(struct clock_event_device *d)
++{
++ struct tc_clkevt_device *tcd = to_tc_clkevt(d);
++
++ clk_disable(tcd->clk);
++ tcd->clk_enabled = false;
++}
++
++static void tc_clk_enable(struct clock_event_device *d)
++{
++ struct tc_clkevt_device *tcd = to_tc_clkevt(d);
++
++ if (tcd->clk_enabled)
++ return;
++ clk_enable(tcd->clk);
++ tcd->clk_enabled = true;
++}
++
+ static int tc_shutdown(struct clock_event_device *d)
+ {
+ struct tc_clkevt_device *tcd = to_tc_clkevt(d);
+@@ -98,8 +117,14 @@ static int tc_shutdown(struct clock_even
+
+ __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR));
+ __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR));
++ return 0;
++}
++
++static int tc_shutdown_clk_off(struct clock_event_device *d)
++{
++ tc_shutdown(d);
+ if (!clockevent_state_detached(d))
+- clk_disable(tcd->clk);
++ tc_clk_disable(d);
+
+ return 0;
+ }
+@@ -112,7 +137,7 @@ static int tc_set_oneshot(struct clock_e
+ if (clockevent_state_oneshot(d) || clockevent_state_periodic(d))
+ tc_shutdown(d);
+
+- clk_enable(tcd->clk);
++ tc_clk_enable(d);
+
+ /* slow clock, count up to RC, then irq and stop */
+ __raw_writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE |
+@@ -134,7 +159,7 @@ static int tc_set_periodic(struct clock_
+ /* By not making the gentime core emulate periodic mode on top
+ * of oneshot, we get lower overhead and improved accuracy.
+ */
+- clk_enable(tcd->clk);
++ tc_clk_enable(d);
+
+ /* slow clock, count up to RC, then irq and restart */
+ __raw_writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
+@@ -168,7 +193,7 @@ static struct tc_clkevt_device clkevt =
+ /* Should be lower than at91rm9200's system timer */
+ .rating = 125,
+ .set_next_event = tc_next_event,
+- .set_state_shutdown = tc_shutdown,
++ .set_state_shutdown = tc_shutdown_clk_off,
+ .set_state_periodic = tc_set_periodic,
+ .set_state_oneshot = tc_set_oneshot,
+ },
diff --git a/patches/block-blk-mq-use-swait.patch b/patches/block-blk-mq-use-swait.patch
index d0c2e94918e603..84da6e0c5adbd9 100644
--- a/patches/block-blk-mq-use-swait.patch
+++ b/patches/block-blk-mq-use-swait.patch
@@ -59,7 +59,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
container_of(ref, struct request_queue, q_usage_counter);
- wake_up_all(&q->mq_freeze_wq);
-+ swait_wake_all(&q->mq_freeze_wq);
++ swake_up_all(&q->mq_freeze_wq);
}
struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
@@ -68,7 +68,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
__set_bit(QUEUE_FLAG_BYPASS, &q->queue_flags);
- init_waitqueue_head(&q->mq_freeze_wq);
-+ init_swait_head(&q->mq_freeze_wq);
++ init_swait_queue_head(&q->mq_freeze_wq);
/*
* Init percpu_ref in atomic mode so that it's faster to shutdown.
@@ -88,7 +88,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (!freeze_depth) {
percpu_ref_reinit(&q->q_usage_counter);
- wake_up_all(&q->mq_freeze_wq);
-+ swait_wake_all(&q->mq_freeze_wq);
++ swake_up_all(&q->mq_freeze_wq);
}
}
EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue);
@@ -97,7 +97,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
* the queue are notified as well.
*/
- wake_up_all(&q->mq_freeze_wq);
-+ swait_wake_all(&q->mq_freeze_wq);
++ swake_up_all(&q->mq_freeze_wq);
}
bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx)
@@ -108,7 +108,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
#endif
struct rcu_head rcu_head;
- wait_queue_head_t mq_freeze_wq;
-+ struct swait_head mq_freeze_wq;
++ struct swait_queue_head mq_freeze_wq;
struct percpu_ref q_usage_counter;
struct list_head all_q_node;
diff --git a/patches/clocksource-tclib-allow-higher-clockrates.patch b/patches/clocksource-tclib-allow-higher-clockrates.patch
index cb833190e016dc..ca4647a942e16c 100644
--- a/patches/clocksource-tclib-allow-higher-clockrates.patch
+++ b/patches/clocksource-tclib-allow-higher-clockrates.patch
@@ -26,15 +26,15 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
*
* A boot clocksource and clockevent source are also currently needed,
* unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so
-@@ -74,6 +73,7 @@ static struct clocksource clksrc = {
- struct tc_clkevt_device {
+@@ -75,6 +74,7 @@ struct tc_clkevt_device {
struct clock_event_device clkevt;
struct clk *clk;
+ bool clk_enabled;
+ u32 freq;
void __iomem *regs;
};
-@@ -82,13 +82,6 @@ static struct tc_clkevt_device *to_tc_cl
+@@ -83,13 +83,6 @@ static struct tc_clkevt_device *to_tc_cl
return container_of(clkevt, struct tc_clkevt_device, clkevt);
}
@@ -47,19 +47,19 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
- */
static u32 timer_clock;
- static int tc_shutdown(struct clock_event_device *d)
-@@ -114,7 +107,7 @@ static int tc_set_oneshot(struct clock_e
+ static void tc_clk_disable(struct clock_event_device *d)
+@@ -139,7 +132,7 @@ static int tc_set_oneshot(struct clock_e
- clk_enable(tcd->clk);
+ tc_clk_enable(d);
- /* slow clock, count up to RC, then irq and stop */
+ /* count up to RC, then irq and stop */
__raw_writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE |
ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR));
__raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
-@@ -136,10 +129,10 @@ static int tc_set_periodic(struct clock_
+@@ -161,10 +154,10 @@ static int tc_set_periodic(struct clock_
*/
- clk_enable(tcd->clk);
+ tc_clk_enable(d);
- /* slow clock, count up to RC, then irq and restart */
+ /* count up to RC, then irq and restart */
@@ -70,7 +70,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
/* Enable clock and interrupts on RC compare */
__raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
-@@ -166,7 +159,11 @@ static struct tc_clkevt_device clkevt =
+@@ -191,7 +184,11 @@ static struct tc_clkevt_device clkevt =
.features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_ONESHOT,
/* Should be lower than at91rm9200's system timer */
@@ -80,9 +80,9 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+ .rating = 200,
+#endif
.set_next_event = tc_next_event,
- .set_state_shutdown = tc_shutdown,
+ .set_state_shutdown = tc_shutdown_clk_off,
.set_state_periodic = tc_set_periodic,
-@@ -188,8 +185,9 @@ static irqreturn_t ch2_irq(int irq, void
+@@ -213,8 +210,9 @@ static irqreturn_t ch2_irq(int irq, void
return IRQ_NONE;
}
@@ -93,7 +93,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
int ret;
struct clk *t2_clk = tc->clk[2];
int irq = tc->irq[2];
-@@ -210,7 +208,11 @@ static int __init setup_clkevents(struct
+@@ -235,7 +233,11 @@ static int __init setup_clkevents(struct
clkevt.regs = tc->regs;
clkevt.clk = t2_clk;
@@ -106,7 +106,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
clkevt.clkevt.cpumask = cpumask_of(0);
-@@ -221,7 +223,7 @@ static int __init setup_clkevents(struct
+@@ -246,7 +248,7 @@ static int __init setup_clkevents(struct
return ret;
}
@@ -115,7 +115,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
return ret;
}
-@@ -358,7 +360,11 @@ static int __init tcb_clksrc_init(void)
+@@ -383,7 +385,11 @@ static int __init tcb_clksrc_init(void)
goto err_disable_t1;
/* channel 2: periodic and oneshot timer support */
diff --git a/patches/completion-use-simple-wait-queues.patch b/patches/completion-use-simple-wait-queues.patch
index b67e24d4afd450..4b128206a83e0c 100644
--- a/patches/completion-use-simple-wait-queues.patch
+++ b/patches/completion-use-simple-wait-queues.patch
@@ -12,10 +12,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
drivers/usb/gadget/function/f_fs.c | 2 -
drivers/usb/gadget/legacy/inode.c | 4 +--
include/linux/completion.h | 9 +++-----
+ include/linux/swait.h | 1
include/linux/uprobes.h | 1
kernel/sched/completion.c | 32 ++++++++++++++---------------
kernel/sched/core.c | 10 +++++++--
- 7 files changed, 33 insertions(+), 27 deletions(-)
+ kernel/sched/swait.c | 17 +++++++++++++++
+ 9 files changed, 51 insertions(+), 27 deletions(-)
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -35,7 +37,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
ffs_data_clear(ffs);
BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
- waitqueue_active(&ffs->ep0req_completion.wait));
-+ swaitqueue_active(&ffs->ep0req_completion.wait));
++ swait_active(&ffs->ep0req_completion.wait));
kfree(ffs->dev_name);
kfree(ffs);
}
@@ -67,7 +69,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
*/
-
-#include <linux/wait.h>
-+#include <linux/wait-simple.h>
++#include <linux/swait.h>
/*
* struct completion - structure used to maintain state for a "completion"
@@ -76,12 +78,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
struct completion {
unsigned int done;
- wait_queue_head_t wait;
-+ struct swait_head wait;
++ struct swait_queue_head wait;
};
#define COMPLETION_INITIALIZER(work) \
- { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
-+ { 0, SWAIT_HEAD_INITIALIZER((work).wait) }
++ { 0, __SWAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
#define COMPLETION_INITIALIZER_ONSTACK(work) \
({ init_completion(&work); work; })
@@ -90,10 +92,20 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
{
x->done = 0;
- init_waitqueue_head(&x->wait);
-+ init_swait_head(&x->wait);
++ init_swait_queue_head(&x->wait);
}
/**
+--- a/include/linux/swait.h
++++ b/include/linux/swait.h
+@@ -87,6 +87,7 @@ static inline int swait_active(struct sw
+ extern void swake_up(struct swait_queue_head *q);
+ extern void swake_up_all(struct swait_queue_head *q);
+ extern void swake_up_locked(struct swait_queue_head *q);
++extern void swake_up_all_locked(struct swait_queue_head *q);
+
+ extern void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait);
+ extern void prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait, int state);
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -27,6 +27,7 @@
@@ -115,7 +127,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
x->done++;
- __wake_up_locked(&x->wait, TASK_NORMAL, 1);
- spin_unlock_irqrestore(&x->wait.lock, flags);
-+ __swait_wake_locked(&x->wait, TASK_NORMAL, 1);
++ swake_up_locked(&x->wait);
+ raw_spin_unlock_irqrestore(&x->wait.lock, flags);
}
EXPORT_SYMBOL(complete);
@@ -129,7 +141,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
x->done += UINT_MAX/2;
- __wake_up_locked(&x->wait, TASK_NORMAL, 0);
- spin_unlock_irqrestore(&x->wait.lock, flags);
-+ __swait_wake_locked(&x->wait, TASK_NORMAL, 0);
++ swake_up_all_locked(&x->wait);
+ raw_spin_unlock_irqrestore(&x->wait.lock, flags);
}
EXPORT_SYMBOL(complete_all);
@@ -139,10 +151,10 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
{
if (!x->done) {
- DECLARE_WAITQUEUE(wait, current);
-+ DEFINE_SWAITER(wait);
++ DECLARE_SWAITQUEUE(wait);
- __add_wait_queue_tail_exclusive(&x->wait, &wait);
-+ swait_prepare_locked(&x->wait, &wait);
++ __prepare_to_swait(&x->wait, &wait);
do {
if (signal_pending_state(state, current)) {
timeout = -ERESTARTSYS;
@@ -156,7 +168,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+ raw_spin_lock_irq(&x->wait.lock);
} while (!x->done && timeout);
- __remove_wait_queue(&x->wait, &wait);
-+ swait_finish_locked(&x->wait, &wait);
++ __finish_swait(&x->wait, &wait);
if (!x->done)
return timeout;
}
@@ -222,3 +234,29 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#endif
WARN_ON_ONCE(p->migrate_disable <= 0);
+--- a/kernel/sched/swait.c
++++ b/kernel/sched/swait.c
+@@ -29,6 +29,23 @@ void swake_up_locked(struct swait_queue_
+ }
+ EXPORT_SYMBOL(swake_up_locked);
+
++void swake_up_all_locked(struct swait_queue_head *q)
++{
++ struct swait_queue *curr;
++ int wakes = 0;
++
++ while (!list_empty(&q->task_list)) {
++
++ curr = list_first_entry(&q->task_list, typeof(*curr),
++ task_list);
++ wake_up_process(curr->task);
++ list_del_init(&curr->task_list);
++ wakes++;
++ }
++ WARN_ON(wakes > 2);
++}
++EXPORT_SYMBOL(swake_up_all_locked);
++
+ void swake_up(struct swait_queue_head *q)
+ {
+ unsigned long flags;
diff --git a/patches/genirq-update-irq_set_irqchip_state-documentation.patch b/patches/genirq-update-irq_set_irqchip_state-documentation.patch
index 6b40fdd0041323..2e4440a13fe1d2 100644
--- a/patches/genirq-update-irq_set_irqchip_state-documentation.patch
+++ b/patches/genirq-update-irq_set_irqchip_state-documentation.patch
@@ -1,7 +1,6 @@
-From 85b7f1606fb707c9da7984e052e47cfa12e85e67 Mon Sep 17 00:00:00 2001
From: Josh Cartwright <joshc@ni.com>
Date: Thu, 11 Feb 2016 11:54:00 -0600
-Subject: [PATCH 1/2] genirq: update irq_set_irqchip_state documentation
+Subject: genirq: update irq_set_irqchip_state documentation
On -rt kernels, the use of migrate_disable()/migrate_enable() is
sufficient to guarantee a task isn't moved to another CPU. Update the
diff --git a/patches/latency-hist.patch b/patches/latency-hist.patch
index 6d7948a7c4719e..411216eb3c00b3 100644
--- a/patches/latency-hist.patch
+++ b/patches/latency-hist.patch
@@ -16,14 +16,14 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Documentation/trace/histograms.txt | 186 +++++
include/linux/hrtimer.h | 4
include/linux/sched.h | 6
- include/trace/events/hist.h | 72 ++
+ include/trace/events/hist.h | 73 ++
include/trace/events/latency_hist.h | 29
kernel/time/hrtimer.c | 21
kernel/trace/Kconfig | 104 +++
kernel/trace/Makefile | 4
kernel/trace/latency_hist.c | 1178 ++++++++++++++++++++++++++++++++++++
kernel/trace/trace_irqsoff.c | 11
- 10 files changed, 1615 insertions(+)
+ 10 files changed, 1616 insertions(+)
--- /dev/null
+++ b/Documentation/trace/histograms.txt
@@ -251,7 +251,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
struct mem_cgroup *memcg_in_oom;
--- /dev/null
+++ b/include/trace/events/hist.h
-@@ -0,0 +1,72 @@
+@@ -0,0 +1,73 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM hist
+
@@ -263,6 +263,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+
+#if !defined(CONFIG_PREEMPT_OFF_HIST) && !defined(CONFIG_INTERRUPT_OFF_HIST)
+#define trace_preemptirqsoff_hist(a, b)
++#define trace_preemptirqsoff_hist_rcuidle(a, b)
+#else
+TRACE_EVENT(preemptirqsoff_hist,
+
diff --git a/patches/localversion.patch b/patches/localversion.patch
index 0484a008be4628..487209c1e1991f 100644
--- a/patches/localversion.patch
+++ b/patches/localversion.patch
@@ -1,4 +1,4 @@
-Subject: v4.4.4-rt10
+Subject: v4.4.4-rt11
From: Thomas Gleixner <tglx@linutronix.de>
Date: Fri, 08 Jul 2011 20:25:16 +0200
@@ -10,4 +10,4 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- /dev/null
+++ b/localversion-rt
@@ -0,0 +1 @@
-+-rt10
++-rt11
diff --git a/patches/mm--rt--Fix-generic-kmap_atomic-for-RT b/patches/mm--rt--Fix-generic-kmap_atomic-for-RT.patch
index 6814afe977c97b..6814afe977c97b 100644
--- a/patches/mm--rt--Fix-generic-kmap_atomic-for-RT
+++ b/patches/mm--rt--Fix-generic-kmap_atomic-for-RT.patch
diff --git a/patches/net__Make_synchronize-rcu_expedited_conditional-on-non-rt b/patches/net__Make_synchronize-rcu_expedited_conditional-on-non-rt.patch
index d454b642c4ba33..d454b642c4ba33 100644
--- a/patches/net__Make_synchronize-rcu_expedited_conditional-on-non-rt
+++ b/patches/net__Make_synchronize-rcu_expedited_conditional-on-non-rt.patch
diff --git a/patches/rcu-Eliminate-softirq-processing-from-rcutree.patch b/patches/rcu-Eliminate-softirq-processing-from-rcutree.patch
index 73cf44e168185f..eca80c4e010b26 100644
--- a/patches/rcu-Eliminate-softirq-processing-from-rcutree.patch
+++ b/patches/rcu-Eliminate-softirq-processing-from-rcutree.patch
@@ -35,7 +35,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
#include "tree.h"
#include "rcu.h"
-@@ -2960,18 +2965,17 @@ static void
+@@ -2962,18 +2967,17 @@ static void
/*
* Do RCU core processing for the current CPU.
*/
@@ -56,7 +56,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/*
* Schedule RCU callback invocation. If the specified type of RCU
* does not support RCU priority boosting, just do a direct call,
-@@ -2983,18 +2987,105 @@ static void invoke_rcu_callbacks(struct
+@@ -2985,18 +2989,105 @@ static void invoke_rcu_callbacks(struct
{
if (unlikely(!READ_ONCE(rcu_scheduler_fully_active)))
return;
@@ -168,7 +168,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/*
* Handle any core-RCU processing required by a call_rcu() invocation.
-@@ -4615,7 +4706,6 @@ void __init rcu_init(void)
+@@ -4617,7 +4708,6 @@ void __init rcu_init(void)
if (dump_tree)
rcu_dump_rcu_node_tree(&rcu_sched_state);
__rcu_init_preempt();
diff --git a/patches/rcu-disable-more-spots-of-rcu_bh.patch b/patches/rcu-disable-more-spots-of-rcu_bh.patch
index 3697ffc546f5f7..e6ea86c222f154 100644
--- a/patches/rcu-disable-more-spots-of-rcu_bh.patch
+++ b/patches/rcu-disable-more-spots-of-rcu_bh.patch
@@ -39,7 +39,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
case RCU_SCHED_FLAVOR:
rsp = &rcu_sched_state;
break;
-@@ -4604,7 +4608,9 @@ void __init rcu_init(void)
+@@ -4606,7 +4610,9 @@ void __init rcu_init(void)
rcu_bootup_announce();
rcu_init_geometry();
@@ -51,7 +51,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
rcu_dump_rcu_node_tree(&rcu_sched_state);
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
-@@ -556,7 +556,9 @@ extern struct list_head rcu_struct_flavo
+@@ -557,7 +557,9 @@ extern struct list_head rcu_struct_flavo
*/
extern struct rcu_state rcu_sched_state;
diff --git a/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch b/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch
index 68b0992c89f1a8..d398665373b1f1 100644
--- a/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch
+++ b/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch
@@ -201,7 +201,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
/*
* Force a quiescent state for RCU-sched.
*/
-@@ -3114,6 +3124,7 @@ void call_rcu_sched(struct rcu_head *hea
+@@ -3116,6 +3126,7 @@ void call_rcu_sched(struct rcu_head *hea
}
EXPORT_SYMBOL_GPL(call_rcu_sched);
@@ -209,7 +209,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
/*
* Queue an RCU callback for invocation after a quicker grace period.
*/
-@@ -3122,6 +3133,7 @@ void call_rcu_bh(struct rcu_head *head,
+@@ -3124,6 +3135,7 @@ void call_rcu_bh(struct rcu_head *head,
__call_rcu(head, func, &rcu_bh_state, -1, 0);
}
EXPORT_SYMBOL_GPL(call_rcu_bh);
@@ -217,7 +217,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
/*
* Queue an RCU callback for lazy invocation after a grace period.
-@@ -3213,6 +3225,7 @@ void synchronize_sched(void)
+@@ -3215,6 +3227,7 @@ void synchronize_sched(void)
}
EXPORT_SYMBOL_GPL(synchronize_sched);
@@ -225,7 +225,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
/**
* synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed.
*
-@@ -3239,6 +3252,7 @@ void synchronize_rcu_bh(void)
+@@ -3241,6 +3254,7 @@ void synchronize_rcu_bh(void)
wait_rcu_gp(call_rcu_bh);
}
EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
@@ -233,7 +233,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
/**
* get_state_synchronize_rcu - Snapshot current RCU state
-@@ -4101,6 +4115,7 @@ static void _rcu_barrier(struct rcu_stat
+@@ -4103,6 +4117,7 @@ static void _rcu_barrier(struct rcu_stat
mutex_unlock(&rsp->barrier_mutex);
}
@@ -241,7 +241,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
/**
* rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete.
*/
-@@ -4109,6 +4124,7 @@ void rcu_barrier_bh(void)
+@@ -4111,6 +4126,7 @@ void rcu_barrier_bh(void)
_rcu_barrier(&rcu_bh_state);
}
EXPORT_SYMBOL_GPL(rcu_barrier_bh);
diff --git a/patches/rcu-more-swait-conversions.patch b/patches/rcu-more-swait-conversions.patch
deleted file mode 100644
index 779a02922c54f9..00000000000000
--- a/patches/rcu-more-swait-conversions.patch
+++ /dev/null
@@ -1,212 +0,0 @@
-From: Thomas Gleixner <tglx@linutronix.de>
-Date: Wed, 31 Jul 2013 19:00:35 +0200
-Subject: rcu: use simple waitqueues
-
-Convert RCU's wait-queues into simple waitqueues.
-
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-
-Merged Steven's
-
- static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp) {
-- swait_wake(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
-+ wake_up_all(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
- }
-
-Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
----
- kernel/rcu/tree.c | 16 ++++++++--------
- kernel/rcu/tree.h | 9 +++++----
- kernel/rcu/tree_plugin.h | 18 +++++++++---------
- 3 files changed, 22 insertions(+), 21 deletions(-)
-
---- a/kernel/rcu/tree.c
-+++ b/kernel/rcu/tree.c
-@@ -1637,7 +1637,7 @@ static void rcu_gp_kthread_wake(struct r
- !READ_ONCE(rsp->gp_flags) ||
- !rsp->gp_kthread)
- return;
-- wake_up(&rsp->gp_wq);
-+ swait_wake(&rsp->gp_wq);
- }
-
- /*
-@@ -2102,7 +2102,7 @@ static int __noreturn rcu_gp_kthread(voi
- READ_ONCE(rsp->gpnum),
- TPS("reqwait"));
- rsp->gp_state = RCU_GP_WAIT_GPS;
-- wait_event_interruptible(rsp->gp_wq,
-+ swait_event_interruptible(rsp->gp_wq,
- READ_ONCE(rsp->gp_flags) &
- RCU_GP_FLAG_INIT);
- rsp->gp_state = RCU_GP_DONE_GPS;
-@@ -2132,7 +2132,7 @@ static int __noreturn rcu_gp_kthread(voi
- READ_ONCE(rsp->gpnum),
- TPS("fqswait"));
- rsp->gp_state = RCU_GP_WAIT_FQS;
-- ret = wait_event_interruptible_timeout(rsp->gp_wq,
-+ ret = swait_event_interruptible_timeout(rsp->gp_wq,
- rcu_gp_fqs_check_wake(rsp, &gf), j);
- rsp->gp_state = RCU_GP_DOING_FQS;
- /* Locking provides needed memory barriers. */
-@@ -3554,7 +3554,7 @@ static void __rcu_report_exp_rnp(struct
- raw_spin_unlock_irqrestore(&rnp->lock, flags);
- if (wake) {
- smp_mb(); /* EGP done before wake_up(). */
-- wake_up(&rsp->expedited_wq);
-+ swait_wake(&rsp->expedited_wq);
- }
- break;
- }
-@@ -3811,7 +3811,7 @@ static void synchronize_sched_expedited_
- jiffies_start = jiffies;
-
- for (;;) {
-- ret = wait_event_interruptible_timeout(
-+ ret = swait_event_interruptible_timeout(
- rsp->expedited_wq,
- sync_rcu_preempt_exp_done(rnp_root),
- jiffies_stall);
-@@ -3819,7 +3819,7 @@ static void synchronize_sched_expedited_
- return;
- if (ret < 0) {
- /* Hit a signal, disable CPU stall warnings. */
-- wait_event(rsp->expedited_wq,
-+ swait_event(rsp->expedited_wq,
- sync_rcu_preempt_exp_done(rnp_root));
- return;
- }
-@@ -4487,8 +4487,8 @@ static void __init rcu_init_one(struct r
- }
- }
-
-- init_waitqueue_head(&rsp->gp_wq);
-- init_waitqueue_head(&rsp->expedited_wq);
-+ init_swait_head(&rsp->gp_wq);
-+ init_swait_head(&rsp->expedited_wq);
- rnp = rsp->level[rcu_num_lvls - 1];
- for_each_possible_cpu(i) {
- while (i > rnp->grphi)
---- a/kernel/rcu/tree.h
-+++ b/kernel/rcu/tree.h
-@@ -28,6 +28,7 @@
- #include <linux/cpumask.h>
- #include <linux/seqlock.h>
- #include <linux/stop_machine.h>
-+#include <linux/wait-simple.h>
-
- /*
- * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and
-@@ -241,7 +242,7 @@ struct rcu_node {
- /* Refused to boost: not sure why, though. */
- /* This can happen due to race conditions. */
- #ifdef CONFIG_RCU_NOCB_CPU
-- wait_queue_head_t nocb_gp_wq[2];
-+ struct swait_head nocb_gp_wq[2];
- /* Place for rcu_nocb_kthread() to wait GP. */
- #endif /* #ifdef CONFIG_RCU_NOCB_CPU */
- int need_future_gp[2];
-@@ -393,7 +394,7 @@ struct rcu_data {
- atomic_long_t nocb_q_count_lazy; /* invocation (all stages). */
- struct rcu_head *nocb_follower_head; /* CBs ready to invoke. */
- struct rcu_head **nocb_follower_tail;
-- wait_queue_head_t nocb_wq; /* For nocb kthreads to sleep on. */
-+ struct swait_head nocb_wq; /* For nocb kthreads to sleep on. */
- struct task_struct *nocb_kthread;
- int nocb_defer_wakeup; /* Defer wakeup of nocb_kthread. */
-
-@@ -472,7 +473,7 @@ struct rcu_state {
- unsigned long gpnum; /* Current gp number. */
- unsigned long completed; /* # of last completed gp. */
- struct task_struct *gp_kthread; /* Task for grace periods. */
-- wait_queue_head_t gp_wq; /* Where GP task waits. */
-+ struct swait_head gp_wq; /* Where GP task waits. */
- short gp_flags; /* Commands for GP task. */
- short gp_state; /* GP kthread sleep state. */
-
-@@ -504,7 +505,7 @@ struct rcu_state {
- atomic_long_t expedited_workdone3; /* # done by others #3. */
- atomic_long_t expedited_normal; /* # fallbacks to normal. */
- atomic_t expedited_need_qs; /* # CPUs left to check in. */
-- wait_queue_head_t expedited_wq; /* Wait for check-ins. */
-+ struct swait_head expedited_wq; /* Wait for check-ins. */
- int ncpus_snap; /* # CPUs seen last time. */
-
- unsigned long jiffies_force_qs; /* Time at which to invoke */
---- a/kernel/rcu/tree_plugin.h
-+++ b/kernel/rcu/tree_plugin.h
-@@ -1830,7 +1830,7 @@ early_param("rcu_nocb_poll", parse_rcu_n
- */
- static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
- {
-- wake_up_all(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
-+ swait_wake_all(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
- }
-
- /*
-@@ -1848,8 +1848,8 @@ static void rcu_nocb_gp_set(struct rcu_n
-
- static void rcu_init_one_nocb(struct rcu_node *rnp)
- {
-- init_waitqueue_head(&rnp->nocb_gp_wq[0]);
-- init_waitqueue_head(&rnp->nocb_gp_wq[1]);
-+ init_swait_head(&rnp->nocb_gp_wq[0]);
-+ init_swait_head(&rnp->nocb_gp_wq[1]);
- }
-
- #ifndef CONFIG_RCU_NOCB_CPU_ALL
-@@ -1874,7 +1874,7 @@ static void wake_nocb_leader(struct rcu_
- if (READ_ONCE(rdp_leader->nocb_leader_sleep) || force) {
- /* Prior smp_mb__after_atomic() orders against prior enqueue. */
- WRITE_ONCE(rdp_leader->nocb_leader_sleep, false);
-- wake_up(&rdp_leader->nocb_wq);
-+ swait_wake(&rdp_leader->nocb_wq);
- }
- }
-
-@@ -2087,7 +2087,7 @@ static void rcu_nocb_wait_gp(struct rcu_
- */
- trace_rcu_future_gp(rnp, rdp, c, TPS("StartWait"));
- for (;;) {
-- wait_event_interruptible(
-+ swait_event_interruptible(
- rnp->nocb_gp_wq[c & 0x1],
- (d = ULONG_CMP_GE(READ_ONCE(rnp->completed), c)));
- if (likely(d))
-@@ -2115,7 +2115,7 @@ static void nocb_leader_wait(struct rcu_
- /* Wait for callbacks to appear. */
- if (!rcu_nocb_poll) {
- trace_rcu_nocb_wake(my_rdp->rsp->name, my_rdp->cpu, "Sleep");
-- wait_event_interruptible(my_rdp->nocb_wq,
-+ swait_event_interruptible(my_rdp->nocb_wq,
- !READ_ONCE(my_rdp->nocb_leader_sleep));
- /* Memory barrier handled by smp_mb() calls below and repoll. */
- } else if (firsttime) {
-@@ -2190,7 +2190,7 @@ static void nocb_leader_wait(struct rcu_
- * List was empty, wake up the follower.
- * Memory barriers supplied by atomic_long_add().
- */
-- wake_up(&rdp->nocb_wq);
-+ swait_wake(&rdp->nocb_wq);
- }
- }
-
-@@ -2211,7 +2211,7 @@ static void nocb_follower_wait(struct rc
- if (!rcu_nocb_poll) {
- trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
- "FollowerSleep");
-- wait_event_interruptible(rdp->nocb_wq,
-+ swait_event_interruptible(rdp->nocb_wq,
- READ_ONCE(rdp->nocb_follower_head));
- } else if (firsttime) {
- /* Don't drown trace log with "Poll"! */
-@@ -2370,7 +2370,7 @@ void __init rcu_init_nohz(void)
- static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp)
- {
- rdp->nocb_tail = &rdp->nocb_head;
-- init_waitqueue_head(&rdp->nocb_wq);
-+ init_swait_head(&rdp->nocb_wq);
- rdp->nocb_follower_tail = &rdp->nocb_follower_head;
- }
-
diff --git a/patches/rtmutex--Handle-non-enqueued-waiters-gracefully b/patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch
index 7223153e73cff7..7223153e73cff7 100644
--- a/patches/rtmutex--Handle-non-enqueued-waiters-gracefully
+++ b/patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch
diff --git a/patches/series b/patches/series
index 2e8d0bca9d4233..075616db0f1863 100644
--- a/patches/series
+++ b/patches/series
@@ -7,6 +7,26 @@
############################################################
rtmutex-Make-wait_lock-irq-safe.patch
arm64-replace-read_lock-to-rcu-lock-in-call_step_hoo.patch
+# AT91 queue in ARM-SOC
+0001-clk-at91-make-use-of-syscon-to-share-PMC-registers-i.patch
+0002-clk-at91-make-use-of-syscon-regmap-internally.patch
+0003-clk-at91-remove-IRQ-handling-and-use-polling.patch
+0004-clk-at91-pmc-merge-at91_pmc_init-in-atmel_pmc_probe.patch
+0005-clk-at91-pmc-move-pmc-structures-to-C-file.patch
+0006-ARM-at91-pm-simply-call-at91_pm_init.patch
+0007-ARM-at91-pm-find-and-remap-the-pmc.patch
+0008-ARM-at91-pm-move-idle-functions-to-pm.c.patch
+0009-ARM-at91-remove-useless-includes-and-function-protot.patch
+0010-usb-gadget-atmel-access-the-PMC-using-regmap.patch
+0011-clk-at91-pmc-drop-at91_pmc_base.patch
+0012-clk-at91-pmc-remove-useless-capacities-handling.patch
+0013-clk-at91-remove-useless-includes.patch
+# SWAIT queue in TIP
+0001-wait.-ch-Introduce-the-simple-waitqueue-swait-implem.patch
+0002-kbuild-Add-option-to-turn-incompatible-pointer-check.patch
+0003-KVM-Use-simple-waitqueue-for-vcpu-wq.patch
+0004-rcu-Do-not-call-rcu_nocb_gp_cleanup-while-holding-rn.patch
+0005-rcu-Use-simple-wait-queues-where-possible-in-rcutree.patch
############################################################
# UPSTREAM FIXES, patches pending
@@ -21,6 +41,7 @@ drivers-cpuidle-coupled-fix-warning-cpuidle_coupled_.patch
drivers-media-vsp1_video-fix-compile-error.patch
sc16is7xx_Drop_bogus_use_of_IRQF_ONESHOT.patch
f2fs_Mutex_cant_be_used_by_down_write_nest_lock().patch
+at91_dont_enable_disable_clock.patch
############################################################
# Stuff which needs addressing upstream, but requires more
@@ -31,7 +52,7 @@ rfc-arm-smp-__cpu_disable-fix-sleeping-function-called-from-invalid-context.patc
############################################################
# Stuff broken upstream, need to be sent
############################################################
-rtmutex--Handle-non-enqueued-waiters-gracefully
+rtmutex--Handle-non-enqueued-waiters-gracefully.patch
kernel-sched-fix-preempt_disable_ip-recodring-for-pr.patch
# Wants a different fix for upstream
@@ -366,9 +387,7 @@ rt-serial-warn-fix.patch
# SIMPLE WAITQUEUE
wait.h-include-atomic.h.patch
-wait-simple-implementation.patch
work-simple-Simple-work-queue-implemenation.patch
-rcu-more-swait-conversions.patch
completion-use-simple-wait-queues.patch
fs-aio-simple-simple-work.patch
@@ -430,7 +449,7 @@ jump-label-rt.patch
# NETWORKING
sunrpc-make-svc_xprt_do_enqueue-use-get_cpu_light.patch
-net__Make_synchronize-rcu_expedited_conditional-on-non-rt
+net__Make_synchronize-rcu_expedited_conditional-on-non-rt.patch
skbufhead-raw-lock.patch
net-core-cpuhotplug-drain-input_pkt_queue-lockless.patch
net-move-xmit_recursion-to-per-task-variable-on-RT.patch
@@ -478,7 +497,7 @@ sysfs-realtime-entry.patch
power-disable-highmem-on-rt.patch
mips-disable-highmem-on-rt.patch
mm-rt-kmap-atomic-scheduling.patch
-mm--rt--Fix-generic-kmap_atomic-for-RT
+mm--rt--Fix-generic-kmap_atomic-for-RT.patch
x86-highmem-add-a-already-used-pte-check.patch
arm-highmem-flush-tlb-on-unmap.patch
arm-enable-highmem-for-rt.patch
@@ -491,7 +510,6 @@ ipc-sem-rework-semaphore-wakeups.patch
# KVM require constant freq TSC (smp function call -> cpufreq)
x86-kvm-require-const-tsc-for-rt.patch
KVM-lapic-mark-LAPIC-timer-handler-as-irqsafe.patch
-KVM-use-simple-waitqueue-for-vcpu-wq.patch
# SCSI/FCOE
scsi-fcoe-rt-aware.patch
diff --git a/patches/wait-simple-implementation.patch b/patches/wait-simple-implementation.patch
deleted file mode 100644
index 199b44b0acd01c..00000000000000
--- a/patches/wait-simple-implementation.patch
+++ /dev/null
@@ -1,362 +0,0 @@
-From: Thomas Gleixner <tglx@linutronix.de>
-Date: Mon Dec 12 12:29:04 2011 +0100
-Subject: wait-simple: Simple waitqueue implementation
-
-wait_queue is a swiss army knife and in most of the cases the
-complexity is not needed. For RT waitqueues are a constant source of
-trouble as we can't convert the head lock to a raw spinlock due to
-fancy and long lasting callbacks.
-
-Provide a slim version, which allows RT to replace wait queues. This
-should go mainline as well, as it lowers memory consumption and
-runtime overhead.
-
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-
-smp_mb() added by Steven Rostedt to fix a race condition with swait
-wakeups vs adding items to the list.
----
- include/linux/wait-simple.h | 207 ++++++++++++++++++++++++++++++++++++++++++++
- kernel/sched/Makefile | 2
- kernel/sched/wait-simple.c | 115 ++++++++++++++++++++++++
- 3 files changed, 323 insertions(+), 1 deletion(-)
-
---- /dev/null
-+++ b/include/linux/wait-simple.h
-@@ -0,0 +1,207 @@
-+#ifndef _LINUX_WAIT_SIMPLE_H
-+#define _LINUX_WAIT_SIMPLE_H
-+
-+#include <linux/spinlock.h>
-+#include <linux/list.h>
-+
-+#include <asm/current.h>
-+
-+struct swaiter {
-+ struct task_struct *task;
-+ struct list_head node;
-+};
-+
-+#define DEFINE_SWAITER(name) \
-+ struct swaiter name = { \
-+ .task = current, \
-+ .node = LIST_HEAD_INIT((name).node), \
-+ }
-+
-+struct swait_head {
-+ raw_spinlock_t lock;
-+ struct list_head list;
-+};
-+
-+#define SWAIT_HEAD_INITIALIZER(name) { \
-+ .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \
-+ .list = LIST_HEAD_INIT((name).list), \
-+ }
-+
-+#define DEFINE_SWAIT_HEAD(name) \
-+ struct swait_head name = SWAIT_HEAD_INITIALIZER(name)
-+
-+extern void __init_swait_head(struct swait_head *h, struct lock_class_key *key);
-+
-+#define init_swait_head(swh) \
-+ do { \
-+ static struct lock_class_key __key; \
-+ \
-+ __init_swait_head((swh), &__key); \
-+ } while (0)
-+
-+/*
-+ * Waiter functions
-+ */
-+extern void swait_prepare_locked(struct swait_head *head, struct swaiter *w);
-+extern void swait_prepare(struct swait_head *head, struct swaiter *w, int state);
-+extern void swait_finish_locked(struct swait_head *head, struct swaiter *w);
-+extern void swait_finish(struct swait_head *head, struct swaiter *w);
-+
-+/* Check whether a head has waiters enqueued */
-+static inline bool swaitqueue_active(struct swait_head *h)
-+{
-+ /* Make sure the condition is visible before checking list_empty() */
-+ smp_mb();
-+ return !list_empty(&h->list);
-+}
-+
-+/*
-+ * Wakeup functions
-+ */
-+extern unsigned int __swait_wake(struct swait_head *head, unsigned int state, unsigned int num);
-+extern unsigned int __swait_wake_locked(struct swait_head *head, unsigned int state, unsigned int num);
-+
-+#define swait_wake(head) __swait_wake(head, TASK_NORMAL, 1)
-+#define swait_wake_interruptible(head) __swait_wake(head, TASK_INTERRUPTIBLE, 1)
-+#define swait_wake_all(head) __swait_wake(head, TASK_NORMAL, 0)
-+#define swait_wake_all_interruptible(head) __swait_wake(head, TASK_INTERRUPTIBLE, 0)
-+
-+/*
-+ * Event API
-+ */
-+#define __swait_event(wq, condition) \
-+do { \
-+ DEFINE_SWAITER(__wait); \
-+ \
-+ for (;;) { \
-+ swait_prepare(&wq, &__wait, TASK_UNINTERRUPTIBLE); \
-+ if (condition) \
-+ break; \
-+ schedule(); \
-+ } \
-+ swait_finish(&wq, &__wait); \
-+} while (0)
-+
-+/**
-+ * swait_event - sleep until a condition gets true
-+ * @wq: the waitqueue to wait on
-+ * @condition: a C expression for the event to wait for
-+ *
-+ * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the
-+ * @condition evaluates to true. The @condition is checked each time
-+ * the waitqueue @wq is woken up.
-+ *
-+ * wake_up() has to be called after changing any variable that could
-+ * change the result of the wait condition.
-+ */
-+#define swait_event(wq, condition) \
-+do { \
-+ if (condition) \
-+ break; \
-+ __swait_event(wq, condition); \
-+} while (0)
-+
-+#define __swait_event_interruptible(wq, condition, ret) \
-+do { \
-+ DEFINE_SWAITER(__wait); \
-+ \
-+ for (;;) { \
-+ swait_prepare(&wq, &__wait, TASK_INTERRUPTIBLE); \
-+ if (condition) \
-+ break; \
-+ if (signal_pending(current)) { \
-+ ret = -ERESTARTSYS; \
-+ break; \
-+ } \
-+ schedule(); \
-+ } \
-+ swait_finish(&wq, &__wait); \
-+} while (0)
-+
-+#define __swait_event_interruptible_timeout(wq, condition, ret) \
-+do { \
-+ DEFINE_SWAITER(__wait); \
-+ \
-+ for (;;) { \
-+ swait_prepare(&wq, &__wait, TASK_INTERRUPTIBLE); \
-+ if (condition) \
-+ break; \
-+ if (signal_pending(current)) { \
-+ ret = -ERESTARTSYS; \
-+ break; \
-+ } \
-+ ret = schedule_timeout(ret); \
-+ if (!ret) \
-+ break; \
-+ } \
-+ swait_finish(&wq, &__wait); \
-+} while (0)
-+
-+/**
-+ * swait_event_interruptible - sleep until a condition gets true
-+ * @wq: the waitqueue to wait on
-+ * @condition: a C expression for the event to wait for
-+ *
-+ * The process is put to sleep (TASK_INTERRUPTIBLE) until the
-+ * @condition evaluates to true. The @condition is checked each time
-+ * the waitqueue @wq is woken up.
-+ *
-+ * wake_up() has to be called after changing any variable that could
-+ * change the result of the wait condition.
-+ */
-+#define swait_event_interruptible(wq, condition) \
-+({ \
-+ int __ret = 0; \
-+ if (!(condition)) \
-+ __swait_event_interruptible(wq, condition, __ret); \
-+ __ret; \
-+})
-+
-+#define swait_event_interruptible_timeout(wq, condition, timeout) \
-+({ \
-+ int __ret = timeout; \
-+ if (!(condition)) \
-+ __swait_event_interruptible_timeout(wq, condition, __ret); \
-+ __ret; \
-+})
-+
-+#define __swait_event_timeout(wq, condition, ret) \
-+do { \
-+ DEFINE_SWAITER(__wait); \
-+ \
-+ for (;;) { \
-+ swait_prepare(&wq, &__wait, TASK_UNINTERRUPTIBLE); \
-+ if (condition) \
-+ break; \
-+ ret = schedule_timeout(ret); \
-+ if (!ret) \
-+ break; \
-+ } \
-+ swait_finish(&wq, &__wait); \
-+} while (0)
-+
-+/**
-+ * swait_event_timeout - sleep until a condition gets true or a timeout elapses
-+ * @wq: the waitqueue to wait on
-+ * @condition: a C expression for the event to wait for
-+ * @timeout: timeout, in jiffies
-+ *
-+ * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the
-+ * @condition evaluates to true. The @condition is checked each time
-+ * the waitqueue @wq is woken up.
-+ *
-+ * wake_up() has to be called after changing any variable that could
-+ * change the result of the wait condition.
-+ *
-+ * The function returns 0 if the @timeout elapsed, and the remaining
-+ * jiffies if the condition evaluated to true before the timeout elapsed.
-+ */
-+#define swait_event_timeout(wq, condition, timeout) \
-+({ \
-+ long __ret = timeout; \
-+ if (!(condition)) \
-+ __swait_event_timeout(wq, condition, __ret); \
-+ __ret; \
-+})
-+
-+#endif
---- a/kernel/sched/Makefile
-+++ b/kernel/sched/Makefile
-@@ -13,7 +13,7 @@ endif
-
- obj-y += core.o loadavg.o clock.o cputime.o
- obj-y += idle_task.o fair.o rt.o deadline.o stop_task.o
--obj-y += wait.o completion.o idle.o
-+obj-y += wait.o wait-simple.o completion.o idle.o
- obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o
- obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o
- obj-$(CONFIG_SCHEDSTATS) += stats.o
---- /dev/null
-+++ b/kernel/sched/wait-simple.c
-@@ -0,0 +1,115 @@
-+/*
-+ * Simple waitqueues without fancy flags and callbacks
-+ *
-+ * (C) 2011 Thomas Gleixner <tglx@linutronix.de>
-+ *
-+ * Based on kernel/wait.c
-+ *
-+ * For licencing details see kernel-base/COPYING
-+ */
-+#include <linux/init.h>
-+#include <linux/export.h>
-+#include <linux/sched.h>
-+#include <linux/wait-simple.h>
-+
-+/* Adds w to head->list. Must be called with head->lock locked. */
-+static inline void __swait_enqueue(struct swait_head *head, struct swaiter *w)
-+{
-+ list_add(&w->node, &head->list);
-+ /* We can't let the condition leak before the setting of head */
-+ smp_mb();
-+}
-+
-+/* Removes w from head->list. Must be called with head->lock locked. */
-+static inline void __swait_dequeue(struct swaiter *w)
-+{
-+ list_del_init(&w->node);
-+}
-+
-+void __init_swait_head(struct swait_head *head, struct lock_class_key *key)
-+{
-+ raw_spin_lock_init(&head->lock);
-+ lockdep_set_class(&head->lock, key);
-+ INIT_LIST_HEAD(&head->list);
-+}
-+EXPORT_SYMBOL(__init_swait_head);
-+
-+void swait_prepare_locked(struct swait_head *head, struct swaiter *w)
-+{
-+ w->task = current;
-+ if (list_empty(&w->node))
-+ __swait_enqueue(head, w);
-+}
-+
-+void swait_prepare(struct swait_head *head, struct swaiter *w, int state)
-+{
-+ unsigned long flags;
-+
-+ raw_spin_lock_irqsave(&head->lock, flags);
-+ swait_prepare_locked(head, w);
-+ __set_current_state(state);
-+ raw_spin_unlock_irqrestore(&head->lock, flags);
-+}
-+EXPORT_SYMBOL(swait_prepare);
-+
-+void swait_finish_locked(struct swait_head *head, struct swaiter *w)
-+{
-+ __set_current_state(TASK_RUNNING);
-+ if (w->task)
-+ __swait_dequeue(w);
-+}
-+
-+void swait_finish(struct swait_head *head, struct swaiter *w)
-+{
-+ unsigned long flags;
-+
-+ __set_current_state(TASK_RUNNING);
-+ if (w->task) {
-+ raw_spin_lock_irqsave(&head->lock, flags);
-+ __swait_dequeue(w);
-+ raw_spin_unlock_irqrestore(&head->lock, flags);
-+ }
-+}
-+EXPORT_SYMBOL(swait_finish);
-+
-+unsigned int
-+__swait_wake_locked(struct swait_head *head, unsigned int state, unsigned int num)
-+{
-+ struct swaiter *curr, *next;
-+ int woken = 0;
-+
-+ list_for_each_entry_safe(curr, next, &head->list, node) {
-+ if (wake_up_state(curr->task, state)) {
-+ __swait_dequeue(curr);
-+ /*
-+ * The waiting task can free the waiter as
-+ * soon as curr->task = NULL is written,
-+ * without taking any locks. A memory barrier
-+ * is required here to prevent the following
-+ * store to curr->task from getting ahead of
-+ * the dequeue operation.
-+ */
-+ smp_wmb();
-+ curr->task = NULL;
-+ if (++woken == num)
-+ break;
-+ }
-+ }
-+ return woken;
-+}
-+
-+unsigned int
-+__swait_wake(struct swait_head *head, unsigned int state, unsigned int num)
-+{
-+ unsigned long flags;
-+ int woken;
-+
-+ if (!swaitqueue_active(head))
-+ return 0;
-+
-+ raw_spin_lock_irqsave(&head->lock, flags);
-+ woken = __swait_wake_locked(head, state, num);
-+ raw_spin_unlock_irqrestore(&head->lock, flags);
-+ return woken;
-+}
-+EXPORT_SYMBOL(__swait_wake);
diff --git a/patches/work-simple-Simple-work-queue-implemenation.patch b/patches/work-simple-Simple-work-queue-implemenation.patch
index 74de1a1a9ebaa5..04f9a3a81fee19 100644
--- a/patches/work-simple-Simple-work-queue-implemenation.patch
+++ b/patches/work-simple-Simple-work-queue-implemenation.patch
@@ -50,8 +50,8 @@ Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
obj-y += core.o loadavg.o clock.o cputime.o
obj-y += idle_task.o fair.o rt.o deadline.o stop_task.o
--obj-y += wait.o wait-simple.o completion.o idle.o
-+obj-y += wait.o wait-simple.o work-simple.o completion.o idle.o
+-obj-y += wait.o swait.o completion.o idle.o
++obj-y += wait.o swait.o work-simple.o completion.o idle.o
obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o
obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o
obj-$(CONFIG_SCHEDSTATS) += stats.o
@@ -65,7 +65,7 @@ Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ * PREEMPT_RT_FULL safe. The callbacks are executed in kthread context.
+ */
+
-+#include <linux/wait-simple.h>
++#include <linux/swait.h>
+#include <linux/work-simple.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
@@ -79,7 +79,7 @@ Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+struct sworker {
+ struct list_head events;
-+ struct swait_head wq;
++ struct swait_queue_head wq;
+
+ raw_spinlock_t lock;
+
@@ -140,7 +140,7 @@ Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+ INIT_LIST_HEAD(&worker->events);
+ raw_spin_lock_init(&worker->lock);
-+ init_swait_head(&worker->wq);
++ init_swait_queue_head(&worker->wq);
+
+ worker->task = kthread_run(swork_kthread, worker, "kswork");
+ if (IS_ERR(worker->task)) {
@@ -177,7 +177,7 @@ Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ list_add_tail(&sev->item, &glob_worker->events);
+ raw_spin_unlock_irqrestore(&glob_worker->lock, flags);
+
-+ swait_wake(&glob_worker->wq);
++ swake_up(&glob_worker->wq);
+ return true;
+}
+EXPORT_SYMBOL_GPL(swork_queue);