Home Home > GIT Browse > SLE12-SP4
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Thumshirn <jthumshirn@suse.de>2019-08-09 11:08:03 +0200
committerJohannes Thumshirn <jthumshirn@suse.de>2019-08-09 11:08:03 +0200
commite7fe4e8f4bd5a2021129257eafa4006a4bd47207 (patch)
tree59cfba7179bd4761d03ddb75c2a81adcb433a86e
parent6dddbfbba8be88dfc37a774f449819d6f2dd7cbc (diff)
parent191d6c3103c62f6ea24634d5fe57838d4649a9b5 (diff)
Merge remote-tracking branch 'origin/SLE15' into SLE12-SP4
Conflicts: blacklist.conf series.conf
-rw-r--r--blacklist.conf3
-rw-r--r--config/arm64/default2
-rw-r--r--patches.arch/0003-dma-introduce-dma_max_mapping_size10
-rw-r--r--patches.arch/s390-sles15-17-02-02-s390-qeth-sanitize-strings-in-debug-messages.patch4
-rw-r--r--patches.arch/x86-microcode-fix-the-microcode-load-on-cpu-hotplug-for-real.patch65
-rw-r--r--patches.drivers/0001-clk-add-clk_bulk_get-accessories.patch415
-rw-r--r--patches.drivers/0001-clk-rockchip-Add-1.6GHz-PLL-rate-for-rk3399.patch35
-rw-r--r--patches.drivers/0002-clk-Export-clk_bulk_prepare.patch36
-rw-r--r--patches.drivers/0002-clk-rockchip-assign-correct-id-for-pclk_ddr-and-hclk.patch49
-rw-r--r--patches.drivers/0003-clk-bulk-silently-error-out-on-EPROBE_DEFER.patch38
-rw-r--r--patches.drivers/0003-soc-rockchip-power-domain-use-clk_bulk-APIs.patch218
-rw-r--r--patches.drivers/0004-soc-rockchip-power-domain-Add-a-sanity-check-on-pd-n.patch52
-rw-r--r--patches.drivers/0005-soc-rockchip-power-domain-Use-of_clk_get_parent_coun.patch48
-rw-r--r--patches.drivers/0007-PM-devfreq-rk3399_dmc-remove-wait-for-dcf-irq-event.patch126
-rw-r--r--patches.drivers/0008-PM-devfreq-rk3399_dmc-do-not-print-error-when-get-su.patch48
-rw-r--r--patches.drivers/0009-PM-devfreq-rk3399_dmc-fix-spelling-mistakes.patch64
-rw-r--r--patches.drivers/0010-PM-devfreq-rk3399_dmc-remove-unneeded-semicolon.patch34
-rw-r--r--patches.drivers/0011-PM-devfreq-rockchip-dfi-Move-GRF-definitions-to-a-co.patch110
-rw-r--r--patches.drivers/0012-PM-devfreq-rk3399_dmc-Pass-ODT-and-auto-power-down-p.patch178
-rw-r--r--patches.drivers/clk-bcm2835-remove-pllb.patch57
-rw-r--r--patches.drivers/clk-bcm283x-add-driver-interfacing-with-raspberry-pi-s-firmware.patch347
-rw-r--r--patches.drivers/clk-raspberrypi-register-platform-device-for-raspberrypi-cpufreq.patch67
-rw-r--r--patches.drivers/cpufreq-add-driver-for-raspberry-pi.patch179
-rw-r--r--patches.drivers/cpufreq-dt-try-freeing-static-opps-only-if-we-have-added-them.patch111
-rw-r--r--patches.drivers/firmware-raspberrypi-register-clk-device.patch60
-rw-r--r--patches.drivers/pm-opp-of-use-pr_debug-instead-of-pr_err-while-adding-opp-table.patch45
-rw-r--r--patches.drm/drm-i915-userptr-Acquire-the-page-lock-around-set_pa.patch56
-rw-r--r--patches.drm/drm-nouveau-fix-memory-leak-in-nouveau_conn_reset.patch63
-rw-r--r--patches.fixes/s390-qeth-avoid-control-io-completion-stalls120
-rw-r--r--patches.fixes/s390-qeth-cancel-cmd-on-early-error135
-rw-r--r--patches.fixes/s390-qeth-fix-request-side-race-during-cmd-io-timeout206
-rw-r--r--patches.fixes/s390-qeth-release-cmd-buffer-in-error-paths62
-rw-r--r--patches.fixes/s390-qeth-simplify-reply-object-handling231
-rw-r--r--patches.kabi/0001-kABI-Preserve-kABI-for-dma_max_mapping_size.patch21
-rw-r--r--patches.kabi/kabi-x86-microcode-hotplug-state-fix.patch8
-rw-r--r--patches.suse/0031-bcache-use-sysfs_match_string-instead-of-__sysfs_mat.patch102
-rw-r--r--patches.suse/0032-bcache-add-return-value-check-to-bch_cached_dev_run.patch4
-rw-r--r--scripts/git_sort/README.md2
-rw-r--r--scripts/git_sort/lib.py80
-rwxr-xr-xscripts/git_sort/merge_tool.py8
-rwxr-xr-xscripts/run_oldconfig.sh3
-rw-r--r--series.conf30
-rw-r--r--supported.conf3
43 files changed, 3409 insertions, 126 deletions
diff --git a/blacklist.conf b/blacklist.conf
index 60574d33fa..81914ee0a3 100644
--- a/blacklist.conf
+++ b/blacklist.conf
@@ -1307,3 +1307,6 @@ f9927000cb35f250051f0f1878db12ee2626eea1 # ASoC: sun4i: not applicable
83ee240aad9147ed5dac5a7c7b4c559d134072e7 # ASoC: cx2072x: superfluous
fd14f4436fd47d5418023c90e933e66d3645552e # ASoC: davinci: not applicable
af31b04b67f4fd7f639fd465a507c154c46fc9fb # NV-DIMM unit test code only
+6ae865615fc43d014da2fd1f1bba7e81ee622d1b # UBSAN bug which we don't use
+81c7ed296dcd02bc0b4488246d040e03e633737a # We don't support CONFIG_X86_5LEVEL
+c1887159eb48ba40e775584cfb2a443962cf1a05 # Clang fix
diff --git a/config/arm64/default b/config/arm64/default
index 578c6e8154..04d9b92d19 100644
--- a/config/arm64/default
+++ b/config/arm64/default
@@ -754,6 +754,7 @@ CONFIG_ARM_DT_BL_CPUFREQ=m
# CONFIG_ARM_DB8500_CPUFREQ is not set
# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
CONFIG_ARM_MT8173_CPUFREQ=m
+CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
CONFIG_ARM_SCPI_CPUFREQ=m
# CONFIG_ARM_TEGRA20_CPUFREQ is not set
# CONFIG_ARM_TEGRA124_CPUFREQ is not set
@@ -6543,6 +6544,7 @@ CONFIG_COMMON_CLK_PWM=m
CONFIG_COMMON_CLK_VC5=m
CONFIG_COMMON_CLK_IPROC=y
CONFIG_CLK_BCM_NS2=y
+CONFIG_CLK_RASPBERRYPI=m
# CONFIG_COMMON_CLK_HI3516CV300 is not set
CONFIG_COMMON_CLK_HI3519=m
CONFIG_COMMON_CLK_HI3660=y
diff --git a/patches.arch/0003-dma-introduce-dma_max_mapping_size b/patches.arch/0003-dma-introduce-dma_max_mapping_size
index b8db1f4644..baa380167e 100644
--- a/patches.arch/0003-dma-introduce-dma_max_mapping_size
+++ b/patches.arch/0003-dma-introduce-dma_max_mapping_size
@@ -84,3 +84,13 @@ Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
};
/*
+--- a/arch/x86/mm/mem_encrypt.c
++++ b/arch/x86/mm/mem_encrypt.c
+@@ -424,6 +424,7 @@ static const struct dma_map_ops sev_dma_
+ .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+ .sync_sg_for_device = swiotlb_sync_sg_for_device,
+ .mapping_error = swiotlb_dma_mapping_error,
++ .max_mapping_size = swiotlb_max_mapping_size,
+ };
+
+ /* Architecture __weak replacement functions */
diff --git a/patches.arch/s390-sles15-17-02-02-s390-qeth-sanitize-strings-in-debug-messages.patch b/patches.arch/s390-sles15-17-02-02-s390-qeth-sanitize-strings-in-debug-messages.patch
index 624f9b88bb..1409f62a6d 100644
--- a/patches.arch/s390-sles15-17-02-02-s390-qeth-sanitize-strings-in-debug-messages.patch
+++ b/patches.arch/s390-sles15-17-02-02-s390-qeth-sanitize-strings-in-debug-messages.patch
@@ -182,8 +182,8 @@ Acked-by: Petr Tesarik <ptesarik@suse.com>
+ QETH_DBF_MESSAGE(2, "IDX activate timed out on channel %x\n",
+ CCW_DEVID(channel->ccwdev));
QETH_DBF_TEXT_(SETUP, 2, "2err%d", -ETIME);
- qeth_clear_cmd_buffers(channel);
return -ETIME;
+ }
@@ -1959,17 +1957,15 @@ static void qeth_idx_write_cb(struct qet
"The adapter is used exclusively by another "
"host\n");
@@ -234,7 +234,7 @@ Acked-by: Petr Tesarik <ptesarik@suse.com>
}
memcpy(&card->token.issuer_rm_r,
@@ -2129,9 +2123,8 @@ int qeth_send_control_data(struct qeth_c
- (addr_t) iob, 0, 0);
+ (addr_t) iob, 0, 0, event_timeout);
spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
if (rc) {
- QETH_DBF_MESSAGE(2, "%s qeth_send_control_data: "
diff --git a/patches.arch/x86-microcode-fix-the-microcode-load-on-cpu-hotplug-for-real.patch b/patches.arch/x86-microcode-fix-the-microcode-load-on-cpu-hotplug-for-real.patch
new file mode 100644
index 0000000000..36d7d31b73
--- /dev/null
+++ b/patches.arch/x86-microcode-fix-the-microcode-load-on-cpu-hotplug-for-real.patch
@@ -0,0 +1,65 @@
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 18 Jun 2019 22:31:40 +0200
+Subject: x86/microcode: Fix the microcode load on CPU hotplug for real
+Git-commit: 5423f5ce5ca410b3646f355279e4e937d452e622
+Patch-mainline: v5.2-rc7
+References: bsc#1114279
+
+A recent change moved the microcode loader hotplug callback into the early
+startup phase which is running with interrupts disabled. It missed that
+the callbacks invoke sysfs functions which might sleep causing nice 'might
+sleep' splats with proper debugging enabled.
+
+Split the callbacks and only load the microcode in the early startup phase
+and move the sysfs handling back into the later threaded and preemptible
+bringup phase where it was before.
+
+Fixes: 78f4e932f776 ("x86/microcode, cpuhotplug: Add a microcode loader CPU hotplug callback")
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: stable@vger.kernel.org
+Cc: x86-ml <x86@kernel.org>
+Link: https://lkml.kernel.org/r/alpine.DEB.2.21.1906182228350.1766@nanos.tec.linutronix.de
+---
+ arch/x86/kernel/cpu/microcode/core.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index a813987b5552..cb0fdcaf1415 100644
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -789,13 +789,16 @@ static struct syscore_ops mc_syscore_ops = {
+ .resume = mc_bp_resume,
+ };
+
+-static int mc_cpu_online(unsigned int cpu)
++static int mc_cpu_starting(unsigned int cpu)
+ {
+- struct device *dev;
+-
+- dev = get_cpu_device(cpu);
+ microcode_update_cpu(cpu);
+ pr_debug("CPU%d added\n", cpu);
++ return 0;
++}
++
++static int mc_cpu_online(unsigned int cpu)
++{
++ struct device *dev = get_cpu_device(cpu);
+
+ if (sysfs_create_group(&dev->kobj, &mc_attr_group))
+ pr_err("Failed to create group for CPU%d\n", cpu);
+@@ -872,7 +875,9 @@ int __init microcode_init(void)
+ goto out_ucode_group;
+
+ register_syscore_ops(&mc_syscore_ops);
+- cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:online",
++ cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:starting",
++ mc_cpu_starting, NULL);
++ cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/microcode:online",
+ mc_cpu_online, mc_cpu_down_prep);
+
+ pr_info("Microcode Update Driver: v%s.", DRIVER_VERSION);
+
diff --git a/patches.drivers/0001-clk-add-clk_bulk_get-accessories.patch b/patches.drivers/0001-clk-add-clk_bulk_get-accessories.patch
new file mode 100644
index 0000000000..eee51d7bba
--- /dev/null
+++ b/patches.drivers/0001-clk-add-clk_bulk_get-accessories.patch
@@ -0,0 +1,415 @@
+From: Dong Aisheng <aisheng.dong@nxp.com>
+Date: Fri, 19 May 2017 21:49:04 +0800
+Subject: clk: add clk_bulk_get accessories
+
+Git-commit: 266e4e9d9150e98141b85c7400f8aa3cd57a7f9b
+Patch-mainline: v4.13-rc1
+References: bsc#1144813
+
+These helper function allows drivers to get several clk consumers in
+one operation. If any of the clk cannot be acquired then any clks
+that were got will be put before returning to the caller.
+
+This can relieve the driver owners' life who needs to handle many clocks,
+as well as each clock error reporting.
+
+Cc: Michael Turquette <mturquette@baylibre.com>
+Cc: Stephen Boyd <sboyd@codeaurora.org>
+Cc: Russell King <linux@arm.linux.org.uk>
+Cc: Geert Uytterhoeven <geert@linux-m68k.org>
+Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
+Cc: Viresh Kumar <viresh.kumar@linaro.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: Fabio Estevam <fabio.estevam@nxp.com>
+Cc: Sascha Hauer <kernel@pengutronix.de>
+Cc: Anson Huang <anson.huang@nxp.com>
+Cc: Robin Gong <yibin.gong@nxp.com>
+Cc: Bai Ping <ping.bai@nxp.com>
+Cc: Leonard Crestez <leonard.crestez@nxp.com>
+Cc: Octavian Purdila <octavian.purdila@nxp.com>
+Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/clk/Makefile | 2 +-
+ drivers/clk/clk-bulk.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/clk.h | 111 ++++++++++++++++++++++++++++++++++
+ 3 files changed, 269 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/clk/clk-bulk.c
+
+diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
+index c19983afcb81..ed1e99f19ec3 100644
+--- a/drivers/clk/Makefile
++++ b/drivers/clk/Makefile
+@@ -1,5 +1,5 @@
+ # common clock types
+-obj-$(CONFIG_HAVE_CLK) += clk-devres.o
++obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o
+ obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
+ obj-$(CONFIG_COMMON_CLK) += clk.o
+ obj-$(CONFIG_COMMON_CLK) += clk-divider.o
+diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c
+new file mode 100644
+index 000000000000..c834f5abfc49
+--- /dev/null
++++ b/drivers/clk/clk-bulk.c
+@@ -0,0 +1,157 @@
++/*
++ * Copyright 2017 NXP
++ *
++ * Dong Aisheng <aisheng.dong@nxp.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <linux/clk.h>
++#include <linux/device.h>
++#include <linux/export.h>
++
++void clk_bulk_put(int num_clks, struct clk_bulk_data *clks)
++{
++ while (--num_clks >= 0) {
++ clk_put(clks[num_clks].clk);
++ clks[num_clks].clk = NULL;
++ }
++}
++EXPORT_SYMBOL_GPL(clk_bulk_put);
++
++int __must_check clk_bulk_get(struct device *dev, int num_clks,
++ struct clk_bulk_data *clks)
++{
++ int ret;
++ int i;
++
++ for (i = 0; i < num_clks; i++)
++ clks[i].clk = NULL;
++
++ for (i = 0; i < num_clks; i++) {
++ clks[i].clk = clk_get(dev, clks[i].id);
++ if (IS_ERR(clks[i].clk)) {
++ ret = PTR_ERR(clks[i].clk);
++ dev_err(dev, "Failed to get clk '%s': %d\n",
++ clks[i].id, ret);
++ clks[i].clk = NULL;
++ goto err;
++ }
++ }
++
++ return 0;
++
++err:
++ clk_bulk_put(i, clks);
++
++ return ret;
++}
++EXPORT_SYMBOL(clk_bulk_get);
++
++#ifdef CONFIG_HAVE_CLK_PREPARE
++
++/**
++ * clk_bulk_unprepare - undo preparation of a set of clock sources
++ * @num_clks: the number of clk_bulk_data
++ * @clks: the clk_bulk_data table being unprepared
++ *
++ * clk_bulk_unprepare may sleep, which differentiates it from clk_bulk_disable.
++ * Returns 0 on success, -EERROR otherwise.
++ */
++void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks)
++{
++ while (--num_clks >= 0)
++ clk_unprepare(clks[num_clks].clk);
++}
++EXPORT_SYMBOL_GPL(clk_bulk_unprepare);
++
++/**
++ * clk_bulk_prepare - prepare a set of clocks
++ * @num_clks: the number of clk_bulk_data
++ * @clks: the clk_bulk_data table being prepared
++ *
++ * clk_bulk_prepare may sleep, which differentiates it from clk_bulk_enable.
++ * Returns 0 on success, -EERROR otherwise.
++ */
++int __must_check clk_bulk_prepare(int num_clks,
++ const struct clk_bulk_data *clks)
++{
++ int ret;
++ int i;
++
++ for (i = 0; i < num_clks; i++) {
++ ret = clk_prepare(clks[i].clk);
++ if (ret) {
++ pr_err("Failed to prepare clk '%s': %d\n",
++ clks[i].id, ret);
++ goto err;
++ }
++ }
++
++ return 0;
++
++err:
++ clk_bulk_unprepare(i, clks);
++
++ return ret;
++}
++
++#endif /* CONFIG_HAVE_CLK_PREPARE */
++
++/**
++ * clk_bulk_disable - gate a set of clocks
++ * @num_clks: the number of clk_bulk_data
++ * @clks: the clk_bulk_data table being gated
++ *
++ * clk_bulk_disable must not sleep, which differentiates it from
++ * clk_bulk_unprepare. clk_bulk_disable must be called before
++ * clk_bulk_unprepare.
++ */
++void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks)
++{
++
++ while (--num_clks >= 0)
++ clk_disable(clks[num_clks].clk);
++}
++EXPORT_SYMBOL_GPL(clk_bulk_disable);
++
++/**
++ * clk_bulk_enable - ungate a set of clocks
++ * @num_clks: the number of clk_bulk_data
++ * @clks: the clk_bulk_data table being ungated
++ *
++ * clk_bulk_enable must not sleep
++ * Returns 0 on success, -EERROR otherwise.
++ */
++int __must_check clk_bulk_enable(int num_clks, const struct clk_bulk_data *clks)
++{
++ int ret;
++ int i;
++
++ for (i = 0; i < num_clks; i++) {
++ ret = clk_enable(clks[i].clk);
++ if (ret) {
++ pr_err("Failed to enable clk '%s': %d\n",
++ clks[i].id, ret);
++ goto err;
++ }
++ }
++
++ return 0;
++
++err:
++ clk_bulk_disable(i, clks);
++
++ return ret;
++}
++EXPORT_SYMBOL_GPL(clk_bulk_enable);
+diff --git a/include/linux/clk.h b/include/linux/clk.h
+index 024cd07870d0..72b0cfce9165 100644
+--- a/include/linux/clk.h
++++ b/include/linux/clk.h
+@@ -77,6 +77,21 @@ struct clk_notifier_data {
+ unsigned long new_rate;
+ };
+
++/**
++ * struct clk_bulk_data - Data used for bulk clk operations.
++ *
++ * @id: clock consumer ID
++ * @clk: struct clk * to store the associated clock
++ *
++ * The CLK APIs provide a series of clk_bulk_() API calls as
++ * a convenience to consumers which require multiple clks. This
++ * structure is used to manage data for these calls.
++ */
++struct clk_bulk_data {
++ const char *id;
++ struct clk *clk;
++};
++
+ #ifdef CONFIG_COMMON_CLK
+
+ /**
+@@ -185,12 +200,20 @@ static inline bool clk_is_match(const struct clk *p, const struct clk *q)
+ */
+ #ifdef CONFIG_HAVE_CLK_PREPARE
+ int clk_prepare(struct clk *clk);
++int __must_check clk_bulk_prepare(int num_clks,
++ const struct clk_bulk_data *clks);
+ #else
+ static inline int clk_prepare(struct clk *clk)
+ {
+ might_sleep();
+ return 0;
+ }
++
++static inline int clk_bulk_prepare(int num_clks, struct clk_bulk_data *clks)
++{
++ might_sleep();
++ return 0;
++}
+ #endif
+
+ /**
+@@ -204,11 +227,16 @@ static inline int clk_prepare(struct clk *clk)
+ */
+ #ifdef CONFIG_HAVE_CLK_PREPARE
+ void clk_unprepare(struct clk *clk);
++void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks);
+ #else
+ static inline void clk_unprepare(struct clk *clk)
+ {
+ might_sleep();
+ }
++static inline void clk_bulk_unprepare(int num_clks, struct clk_bulk_data *clks)
++{
++ might_sleep();
++}
+ #endif
+
+ #ifdef CONFIG_HAVE_CLK
+@@ -230,6 +258,29 @@ static inline void clk_unprepare(struct clk *clk)
+ struct clk *clk_get(struct device *dev, const char *id);
+
+ /**
++ * clk_bulk_get - lookup and obtain a number of references to clock producer.
++ * @dev: device for clock "consumer"
++ * @num_clks: the number of clk_bulk_data
++ * @clks: the clk_bulk_data table of consumer
++ *
++ * This helper function allows drivers to get several clk consumers in one
++ * operation. If any of the clk cannot be acquired then any clks
++ * that were obtained will be freed before returning to the caller.
++ *
++ * Returns 0 if all clocks specified in clk_bulk_data table are obtained
++ * successfully, or valid IS_ERR() condition containing errno.
++ * The implementation uses @dev and @clk_bulk_data.id to determine the
++ * clock consumer, and thereby the clock producer.
++ * The clock returned is stored in each @clk_bulk_data.clk field.
++ *
++ * Drivers must assume that the clock source is not enabled.
++ *
++ * clk_bulk_get should not be called from within interrupt context.
++ */
++int __must_check clk_bulk_get(struct device *dev, int num_clks,
++ struct clk_bulk_data *clks);
++
++/**
+ * devm_clk_get - lookup and obtain a managed reference to a clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+@@ -279,6 +330,18 @@ struct clk *devm_get_clk_from_child(struct device *dev,
+ int clk_enable(struct clk *clk);
+
+ /**
++ * clk_bulk_enable - inform the system when the set of clks should be running.
++ * @num_clks: the number of clk_bulk_data
++ * @clks: the clk_bulk_data table of consumer
++ *
++ * May be called from atomic contexts.
++ *
++ * Returns success (0) or negative errno.
++ */
++int __must_check clk_bulk_enable(int num_clks,
++ const struct clk_bulk_data *clks);
++
++/**
+ * clk_disable - inform the system when the clock source is no longer required.
+ * @clk: clock source
+ *
+@@ -295,6 +358,24 @@ int clk_enable(struct clk *clk);
+ void clk_disable(struct clk *clk);
+
+ /**
++ * clk_bulk_disable - inform the system when the set of clks is no
++ * longer required.
++ * @num_clks: the number of clk_bulk_data
++ * @clks: the clk_bulk_data table of consumer
++ *
++ * Inform the system that a set of clks is no longer required by
++ * a driver and may be shut down.
++ *
++ * May be called from atomic contexts.
++ *
++ * Implementation detail: if the set of clks is shared between
++ * multiple drivers, clk_bulk_enable() calls must be balanced by the
++ * same number of clk_bulk_disable() calls for the clock source to be
++ * disabled.
++ */
++void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks);
++
++/**
+ * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
+ * This is only valid once the clock source has been enabled.
+ * @clk: clock source
+@@ -314,6 +395,19 @@ unsigned long clk_get_rate(struct clk *clk);
+ void clk_put(struct clk *clk);
+
+ /**
++ * clk_bulk_put - "free" the clock source
++ * @num_clks: the number of clk_bulk_data
++ * @clks: the clk_bulk_data table of consumer
++ *
++ * Note: drivers must ensure that all clk_bulk_enable calls made on this
++ * clock source are balanced by clk_bulk_disable calls prior to calling
++ * this function.
++ *
++ * clk_bulk_put should not be called from within interrupt context.
++ */
++void clk_bulk_put(int num_clks, struct clk_bulk_data *clks);
++
++/**
+ * devm_clk_put - "free" a managed clock source
+ * @dev: device used to acquire the clock
+ * @clk: clock source acquired with devm_clk_get()
+@@ -445,6 +539,12 @@ static inline struct clk *clk_get(struct device *dev, const char *id)
+ return NULL;
+ }
+
++static inline int clk_bulk_get(struct device *dev, int num_clks,
++ struct clk_bulk_data *clks)
++{
++ return 0;
++}
++
+ static inline struct clk *devm_clk_get(struct device *dev, const char *id)
+ {
+ return NULL;
+@@ -458,6 +558,8 @@ static inline struct clk *devm_get_clk_from_child(struct device *dev,
+
+ static inline void clk_put(struct clk *clk) {}
+
++static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {}
++
+ static inline void devm_clk_put(struct device *dev, struct clk *clk) {}
+
+ static inline int clk_enable(struct clk *clk)
+@@ -465,8 +567,17 @@ static inline int clk_enable(struct clk *clk)
+ return 0;
+ }
+
++static inline int clk_bulk_enable(int num_clks, struct clk_bulk_data *clks)
++{
++ return 0;
++}
++
+ static inline void clk_disable(struct clk *clk) {}
+
++
++static inline void clk_bulk_disable(int num_clks,
++ struct clk_bulk_data *clks) {}
++
+ static inline unsigned long clk_get_rate(struct clk *clk)
+ {
+ return 0;
+--
+2.11.0
+
diff --git a/patches.drivers/0001-clk-rockchip-Add-1.6GHz-PLL-rate-for-rk3399.patch b/patches.drivers/0001-clk-rockchip-Add-1.6GHz-PLL-rate-for-rk3399.patch
new file mode 100644
index 0000000000..96ba76d585
--- /dev/null
+++ b/patches.drivers/0001-clk-rockchip-Add-1.6GHz-PLL-rate-for-rk3399.patch
@@ -0,0 +1,35 @@
+From: Derek Basehore <dbasehore@chromium.org>
+Date: Tue, 13 Mar 2018 13:37:19 -0700
+Subject: clk: rockchip: Add 1.6GHz PLL rate for rk3399
+
+Git-commit: 4ee3fd4abeca30d530fe67972f1964f7454259d6
+Patch-mainline: v4.17-rc1
+References: bsc#1144718,bsc#1144813
+
+We need this rate to generate 100, 200, and 228.57MHz from the same
+PLL. 228.57MHz is useful for a pixel clock when the VPLL is used for
+an external display.
+
+Signed-off-by: Derek Basehore <dbasehore@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/clk/rockchip/clk-rk3399.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
+index 6847120b61cd..3e57c6eef93d 100644
+--- a/drivers/clk/rockchip/clk-rk3399.c
++++ b/drivers/clk/rockchip/clk-rk3399.c
+@@ -57,6 +57,7 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = {
+ RK3036_PLL_RATE(1656000000, 1, 69, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1632000000, 1, 68, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
++ RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
+--
+2.11.0
+
diff --git a/patches.drivers/0002-clk-Export-clk_bulk_prepare.patch b/patches.drivers/0002-clk-Export-clk_bulk_prepare.patch
new file mode 100644
index 0000000000..97f2d880a8
--- /dev/null
+++ b/patches.drivers/0002-clk-Export-clk_bulk_prepare.patch
@@ -0,0 +1,36 @@
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+Date: Fri, 22 Sep 2017 22:00:29 -0700
+Subject: clk: Export clk_bulk_prepare()
+
+Git-commit: 9792bf5ad5e30b207274ccbb459a89eab6033b46
+Patch-mainline: v4.14-rc4
+References: bsc#1144813
+
+Allow clk_bulk_prepare() to be referenced by kernel modules by adding
+the missing EXPORT_SYMBOL_GPL().
+
+Fixes: 266e4e9d9150 ("clk: add clk_bulk_get accessories")
+Reported-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/clk/clk-bulk.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c
+index c834f5abfc49..4c10456f8a32 100644
+--- a/drivers/clk/clk-bulk.c
++++ b/drivers/clk/clk-bulk.c
+@@ -105,6 +105,7 @@ int __must_check clk_bulk_prepare(int num_clks,
+
+ return ret;
+ }
++EXPORT_SYMBOL_GPL(clk_bulk_prepare);
+
+ #endif /* CONFIG_HAVE_CLK_PREPARE */
+
+--
+2.11.0
+
diff --git a/patches.drivers/0002-clk-rockchip-assign-correct-id-for-pclk_ddr-and-hclk.patch b/patches.drivers/0002-clk-rockchip-assign-correct-id-for-pclk_ddr-and-hclk.patch
new file mode 100644
index 0000000000..e3fea783eb
--- /dev/null
+++ b/patches.drivers/0002-clk-rockchip-assign-correct-id-for-pclk_ddr-and-hclk.patch
@@ -0,0 +1,49 @@
+From: Lin Huang <hl@rock-chips.com>
+Date: Tue, 20 Mar 2018 10:06:28 +0800
+Subject: clk: rockchip: assign correct id for pclk_ddr and hclk_sd in rk3399
+
+Git-commit: 9dc486fdf6cc0d7f635954810ab119c5db2cbb60
+Patch-mainline: v4.17-rc1
+References: bsc#1144718,bsc#1144813
+
+Since hclk_sd and pclk_ddr source clock from CPLL or GPLL,
+and these two PLL may change their frequency. If we do not
+assign right id to pclk_ddr and hclk_sd, they will alway use
+default cur register value, and may get the frequency
+exceed their signed off frequency. So assign correct Id
+for them, then we can assign frequency for them in dts.
+
+Signed-off-by: Lin Huang <hl@rock-chips.com>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/clk/rockchip/clk-rk3399.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
+index 3e57c6eef93d..bca10d618f0a 100644
+--- a/drivers/clk/rockchip/clk-rk3399.c
++++ b/drivers/clk/rockchip/clk-rk3399.c
+@@ -671,7 +671,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
+ RK3399_CLKGATE_CON(9), 7, GFLAGS,
+ &rk3399_uart3_fracmux),
+
+- COMPOSITE(0, "pclk_ddr", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
++ COMPOSITE(PCLK_DDR, "pclk_ddr", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
+ RK3399_CLKSEL_CON(6), 15, 1, MFLAGS, 8, 5, DFLAGS,
+ RK3399_CLKGATE_CON(3), 4, GFLAGS),
+
+@@ -887,7 +887,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
+ RK3399_CLKGATE_CON(31), 8, GFLAGS),
+
+ /* sdio & sdmmc */
+- COMPOSITE(0, "hclk_sd", mux_pll_src_cpll_gpll_p, 0,
++ COMPOSITE(HCLK_SD, "hclk_sd", mux_pll_src_cpll_gpll_p, 0,
+ RK3399_CLKSEL_CON(13), 15, 1, MFLAGS, 8, 5, DFLAGS,
+ RK3399_CLKGATE_CON(12), 13, GFLAGS),
+ GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sd", 0,
+--
+2.11.0
+
diff --git a/patches.drivers/0003-clk-bulk-silently-error-out-on-EPROBE_DEFER.patch b/patches.drivers/0003-clk-bulk-silently-error-out-on-EPROBE_DEFER.patch
new file mode 100644
index 0000000000..e10f3e2a2a
--- /dev/null
+++ b/patches.drivers/0003-clk-bulk-silently-error-out-on-EPROBE_DEFER.patch
@@ -0,0 +1,38 @@
+From: Jerome Brunet <jbrunet@baylibre.com>
+Date: Mon, 9 Apr 2018 16:13:03 +0200
+Subject: clk: bulk: silently error out on EPROBE_DEFER
+
+Git-commit: 329470f2d5447f76088250d7b7fbc1f9b175ccfc
+Patch-mainline: v4.18-rc1
+References: bsc#1144718,bsc#1144813
+
+In clk_bulk_get(), if we fail to get the clock due to probe deferal, we
+shouldn't print an error message. Just be silent in this case.
+
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/clk/clk-bulk.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c
+index 4c10456f8a32..6904ed6da504 100644
+--- a/drivers/clk/clk-bulk.c
++++ b/drivers/clk/clk-bulk.c
+@@ -42,8 +42,9 @@ int __must_check clk_bulk_get(struct device *dev, int num_clks,
+ clks[i].clk = clk_get(dev, clks[i].id);
+ if (IS_ERR(clks[i].clk)) {
+ ret = PTR_ERR(clks[i].clk);
+- dev_err(dev, "Failed to get clk '%s': %d\n",
+- clks[i].id, ret);
++ if (ret != -EPROBE_DEFER)
++ dev_err(dev, "Failed to get clk '%s': %d\n",
++ clks[i].id, ret);
+ clks[i].clk = NULL;
+ goto err;
+ }
+--
+2.11.0
+
diff --git a/patches.drivers/0003-soc-rockchip-power-domain-use-clk_bulk-APIs.patch b/patches.drivers/0003-soc-rockchip-power-domain-use-clk_bulk-APIs.patch
new file mode 100644
index 0000000000..aea936cd10
--- /dev/null
+++ b/patches.drivers/0003-soc-rockchip-power-domain-use-clk_bulk-APIs.patch
@@ -0,0 +1,218 @@
+From: Jeffy Chen <jeffy.chen@rock-chips.com>
+Date: Wed, 28 Feb 2018 20:41:43 +0800
+Subject: soc: rockchip: power-domain: use clk_bulk APIs
+
+Git-commit: d909072d0521a84e67fbe5cce602d7befffabf7e
+Patch-mainline: v4.17-rc1
+References: bsc#1144718,bsc#1144813
+
+Use clk_bulk APIs, and also add error handling for clk enable.
+
+Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/soc/rockchip/pm_domains.c | 90 ++++++++++++++++++---------------------
+ 1 file changed, 42 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
+index 5c342167b9db..ad96ddeaeb78 100644
+--- a/drivers/soc/rockchip/pm_domains.c
++++ b/drivers/soc/rockchip/pm_domains.c
+@@ -67,7 +67,7 @@ struct rockchip_pm_domain {
+ struct regmap **qos_regmap;
+ u32 *qos_save_regs[MAX_QOS_REGS_NUM];
+ int num_clks;
+- struct clk *clks[];
++ struct clk_bulk_data *clks;
+ };
+
+ struct rockchip_pmu {
+@@ -274,13 +274,18 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
+
+ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
+ {
+- int i;
++ struct rockchip_pmu *pmu = pd->pmu;
++ int ret;
+
+- mutex_lock(&pd->pmu->mutex);
++ mutex_lock(&pmu->mutex);
+
+ if (rockchip_pmu_domain_is_on(pd) != power_on) {
+- for (i = 0; i < pd->num_clks; i++)
+- clk_enable(pd->clks[i]);
++ ret = clk_bulk_enable(pd->num_clks, pd->clks);
++ if (ret < 0) {
++ dev_err(pmu->dev, "failed to enable clocks\n");
++ mutex_unlock(&pmu->mutex);
++ return ret;
++ }
+
+ if (!power_on) {
+ rockchip_pmu_save_qos(pd);
+@@ -298,11 +303,10 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
+ rockchip_pmu_restore_qos(pd);
+ }
+
+- for (i = pd->num_clks - 1; i >= 0; i--)
+- clk_disable(pd->clks[i]);
++ clk_bulk_disable(pd->num_clks, pd->clks);
+ }
+
+- mutex_unlock(&pd->pmu->mutex);
++ mutex_unlock(&pmu->mutex);
+ return 0;
+ }
+
+@@ -364,8 +368,6 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+ const struct rockchip_domain_info *pd_info;
+ struct rockchip_pm_domain *pd;
+ struct device_node *qos_node;
+- struct clk *clk;
+- int clk_cnt;
+ int i, j;
+ u32 id;
+ int error;
+@@ -391,41 +393,36 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+ return -EINVAL;
+ }
+
+- clk_cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells");
+- pd = devm_kzalloc(pmu->dev,
+- sizeof(*pd) + clk_cnt * sizeof(pd->clks[0]),
+- GFP_KERNEL);
++ pd = devm_kzalloc(pmu->dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd)
+ return -ENOMEM;
+
+ pd->info = pd_info;
+ pd->pmu = pmu;
+
+- for (i = 0; i < clk_cnt; i++) {
+- clk = of_clk_get(node, i);
+- if (IS_ERR(clk)) {
+- error = PTR_ERR(clk);
++ pd->num_clks = of_count_phandle_with_args(node, "clocks",
++ "#clock-cells");
++
++ pd->clks = devm_kcalloc(pmu->dev, pd->num_clks, sizeof(*pd->clks),
++ GFP_KERNEL);
++ if (!pd->clks)
++ return -ENOMEM;
++
++ for (i = 0; i < pd->num_clks; i++) {
++ pd->clks[i].clk = of_clk_get(node, i);
++ if (IS_ERR(pd->clks[i].clk)) {
++ error = PTR_ERR(pd->clks[i].clk);
+ dev_err(pmu->dev,
+ "%s: failed to get clk at index %d: %d\n",
+ node->name, i, error);
+- goto err_out;
+- }
+-
+- error = clk_prepare(clk);
+- if (error) {
+- dev_err(pmu->dev,
+- "%s: failed to prepare clk %pC (index %d): %d\n",
+- node->name, clk, i, error);
+- clk_put(clk);
+- goto err_out;
++ return error;
+ }
+-
+- pd->clks[pd->num_clks++] = clk;
+-
+- dev_dbg(pmu->dev, "added clock '%pC' to domain '%s'\n",
+- clk, node->name);
+ }
+
++ error = clk_bulk_prepare(pd->num_clks, pd->clks);
++ if (error)
++ goto err_put_clocks;
++
+ pd->num_qos = of_count_phandle_with_args(node, "pm_qos",
+ NULL);
+
+@@ -435,7 +432,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+ GFP_KERNEL);
+ if (!pd->qos_regmap) {
+ error = -ENOMEM;
+- goto err_out;
++ goto err_unprepare_clocks;
+ }
+
+ for (j = 0; j < MAX_QOS_REGS_NUM; j++) {
+@@ -445,7 +442,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+ GFP_KERNEL);
+ if (!pd->qos_save_regs[j]) {
+ error = -ENOMEM;
+- goto err_out;
++ goto err_unprepare_clocks;
+ }
+ }
+
+@@ -453,13 +450,13 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+ qos_node = of_parse_phandle(node, "pm_qos", j);
+ if (!qos_node) {
+ error = -ENODEV;
+- goto err_out;
++ goto err_unprepare_clocks;
+ }
+ pd->qos_regmap[j] = syscon_node_to_regmap(qos_node);
+ if (IS_ERR(pd->qos_regmap[j])) {
+ error = -ENODEV;
+ of_node_put(qos_node);
+- goto err_out;
++ goto err_unprepare_clocks;
+ }
+ of_node_put(qos_node);
+ }
+@@ -470,7 +467,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+ dev_err(pmu->dev,
+ "failed to power on domain '%s': %d\n",
+ node->name, error);
+- goto err_out;
++ goto err_unprepare_clocks;
+ }
+
+ pd->genpd.name = node->name;
+@@ -486,17 +483,16 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+ pmu->genpd_data.domains[id] = &pd->genpd;
+ return 0;
+
+-err_out:
+- while (--i >= 0) {
+- clk_unprepare(pd->clks[i]);
+- clk_put(pd->clks[i]);
+- }
++err_unprepare_clocks:
++ clk_bulk_unprepare(pd->num_clks, pd->clks);
++err_put_clocks:
++ clk_bulk_put(pd->num_clks, pd->clks);
+ return error;
+ }
+
+ static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
+ {
+- int i, ret;
++ int ret;
+
+ /*
+ * We're in the error cleanup already, so we only complain,
+@@ -507,10 +503,8 @@ static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
+ dev_err(pd->pmu->dev, "failed to remove domain '%s' : %d - state may be inconsistent\n",
+ pd->genpd.name, ret);
+
+- for (i = 0; i < pd->num_clks; i++) {
+- clk_unprepare(pd->clks[i]);
+- clk_put(pd->clks[i]);
+- }
++ clk_bulk_unprepare(pd->num_clks, pd->clks);
++ clk_bulk_put(pd->num_clks, pd->clks);
+
+ /* protect the zeroing of pm->num_clks */
+ mutex_lock(&pd->pmu->mutex);
+--
+2.11.0
+
diff --git a/patches.drivers/0004-soc-rockchip-power-domain-Add-a-sanity-check-on-pd-n.patch b/patches.drivers/0004-soc-rockchip-power-domain-Add-a-sanity-check-on-pd-n.patch
new file mode 100644
index 0000000000..705389b784
--- /dev/null
+++ b/patches.drivers/0004-soc-rockchip-power-domain-Add-a-sanity-check-on-pd-n.patch
@@ -0,0 +1,52 @@
+From: Jeffy Chen <jeffy.chen@rock-chips.com>
+Date: Mon, 5 Mar 2018 17:17:22 +0800
+Subject: soc: rockchip: power-domain: Add a sanity check on pd->num_clks
+
+Git-commit: b1271993aa3855bda5073c6061a095fd6e6febc6
+Patch-mainline: v4.17-rc1
+References: bsc#1144718,bsc#1144813
+
+The of_count_phandle_with_args() can fail and return error(for example,
+rk3399 pd_vio doesn't have clocks). That would break the pd probe.
+
+Add a sanity check on pd->num_clks to avoid that.
+
+Fixes: 65084121d59d ("soc: rockchip: power-domain: use clk_bulk APIs")
+Reported-by: Shawn Lin <shawn.lin@rock-chips.com>
+Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
+Tested-by: Shawn Lin <shawn.lin@rock-chips.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/soc/rockchip/pm_domains.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
+index ad96ddeaeb78..53efc386b1ad 100644
+--- a/drivers/soc/rockchip/pm_domains.c
++++ b/drivers/soc/rockchip/pm_domains.c
+@@ -402,11 +402,16 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+
+ pd->num_clks = of_count_phandle_with_args(node, "clocks",
+ "#clock-cells");
+-
+- pd->clks = devm_kcalloc(pmu->dev, pd->num_clks, sizeof(*pd->clks),
+- GFP_KERNEL);
+- if (!pd->clks)
+- return -ENOMEM;
++ if (pd->num_clks > 0) {
++ pd->clks = devm_kcalloc(pmu->dev, pd->num_clks,
++ sizeof(*pd->clks), GFP_KERNEL);
++ if (!pd->clks)
++ return -ENOMEM;
++ } else {
++ dev_dbg(pmu->dev, "%s: doesn't have clocks: %d\n",
++ node->name, pd->num_clks);
++ pd->num_clks = 0;
++ }
+
+ for (i = 0; i < pd->num_clks; i++) {
+ pd->clks[i].clk = of_clk_get(node, i);
+--
+2.11.0
+
diff --git a/patches.drivers/0005-soc-rockchip-power-domain-Use-of_clk_get_parent_coun.patch b/patches.drivers/0005-soc-rockchip-power-domain-Use-of_clk_get_parent_coun.patch
new file mode 100644
index 0000000000..0145ef3e87
--- /dev/null
+++ b/patches.drivers/0005-soc-rockchip-power-domain-Use-of_clk_get_parent_coun.patch
@@ -0,0 +1,48 @@
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Wed, 18 Apr 2018 16:50:03 +0200
+Subject: soc: rockchip: power-domain: Use of_clk_get_parent_count() instead of
+ open coding
+
+Git-commit: 54d52ad940bb50284c85adcf481413fb3b82925a
+Patch-mainline: v4.18-rc1
+References: bsc#1144718,bsc#1144813
+
+As of_clk_get_parent_count() returns zero on failure, while
+of_count_phandle_with_args() might return a negative error code, this
+also fixes the issue of possibly using a negative number in the
+allocation below.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/soc/rockchip/pm_domains.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
+index 53efc386b1ad..13913d40c821 100644
+--- a/drivers/soc/rockchip/pm_domains.c
++++ b/drivers/soc/rockchip/pm_domains.c
+@@ -14,6 +14,7 @@
+ #include <linux/pm_clock.h>
+ #include <linux/pm_domain.h>
+ #include <linux/of_address.h>
++#include <linux/clk-provider.h>
+ #include <linux/of_platform.h>
+ #include <linux/clk.h>
+ #include <linux/regmap.h>
+@@ -400,8 +401,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+ pd->info = pd_info;
+ pd->pmu = pmu;
+
+- pd->num_clks = of_count_phandle_with_args(node, "clocks",
+- "#clock-cells");
++ pd->num_clks = of_clk_get_parent_count(node);
+ if (pd->num_clks > 0) {
+ pd->clks = devm_kcalloc(pmu->dev, pd->num_clks,
+ sizeof(*pd->clks), GFP_KERNEL);
+--
+2.11.0
+
diff --git a/patches.drivers/0007-PM-devfreq-rk3399_dmc-remove-wait-for-dcf-irq-event.patch b/patches.drivers/0007-PM-devfreq-rk3399_dmc-remove-wait-for-dcf-irq-event.patch
new file mode 100644
index 0000000000..a2e2ba9265
--- /dev/null
+++ b/patches.drivers/0007-PM-devfreq-rk3399_dmc-remove-wait-for-dcf-irq-event.patch
@@ -0,0 +1,126 @@
+From: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Date: Wed, 9 May 2018 14:57:45 +0200
+Subject: PM / devfreq: rk3399_dmc: remove wait for dcf irq event.
+
+Git-commit: 90dd72e1290dd86c4b6e5c421fcd13e60e625782
+Patch-mainline: v4.19-rc1
+References: bsc#1144718,bsc#1144813
+
+We have already wait dcf done in ATF, so don't need wait dcf irq
+in kernel, besides, clear dcf irq in kernel will import competiton
+between kernel and ATF, only handle dcf irq in ATF is a better way.
+
+Signed-off-by: Lin Huang <hl@rock-chips.com>
+Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/devfreq/rk3399_dmc.c | 53 +-------------------------------------------
+ 1 file changed, 1 insertion(+), 52 deletions(-)
+
+diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
+index 5dfbfa3cc878..44a379657cd5 100644
+--- a/drivers/devfreq/rk3399_dmc.c
++++ b/drivers/devfreq/rk3399_dmc.c
+@@ -68,15 +68,6 @@ struct rk3399_dmcfreq {
+ struct devfreq_event_dev *edev;
+ struct mutex lock;
+ struct dram_timing timing;
+-
+- /*
+- * DDR Converser of Frequency (DCF) is used to implement DDR frequency
+- * conversion without the participation of CPU, we will implement and
+- * control it in arm trust firmware.
+- */
+- wait_queue_head_t wait_dcf_queue;
+- int irq;
+- int wait_dcf_flag;
+ struct regulator *vdd_center;
+ unsigned long rate, target_rate;
+ unsigned long volt, target_volt;
+@@ -117,7 +108,6 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+ goto out;
+ }
+ }
+- dmcfreq->wait_dcf_flag = 1;
+
+ err = clk_set_rate(dmcfreq->dmc_clk, target_rate);
+ if (err) {
+@@ -129,14 +119,6 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+ }
+
+ /*
+- * Wait until bcf irq happen, it means freq scaling finish in
+- * arm trust firmware, use 100ms as timeout time.
+- */
+- if (!wait_event_timeout(dmcfreq->wait_dcf_queue,
+- !dmcfreq->wait_dcf_flag, HZ / 10))
+- dev_warn(dev, "Timeout waiting for dcf interrupt\n");
+-
+- /*
+ * Check the dpll rate,
+ * There only two result we will get,
+ * 1. Ddr frequency scaling fail, we still get the old rate.
+@@ -241,22 +223,6 @@ static __maybe_unused int rk3399_dmcfreq_resume(struct device *dev)
+ static SIMPLE_DEV_PM_OPS(rk3399_dmcfreq_pm, rk3399_dmcfreq_suspend,
+ rk3399_dmcfreq_resume);
+
+-static irqreturn_t rk3399_dmc_irq(int irq, void *dev_id)
+-{
+- struct rk3399_dmcfreq *dmcfreq = dev_id;
+- struct arm_smccc_res res;
+-
+- dmcfreq->wait_dcf_flag = 0;
+- wake_up(&dmcfreq->wait_dcf_queue);
+-
+- /* Clear the DCF interrupt */
+- arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
+- ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ,
+- 0, 0, 0, 0, &res);
+-
+- return IRQ_HANDLED;
+-}
+-
+ static int of_get_ddr_timings(struct dram_timing *timing,
+ struct device_node *np)
+ {
+@@ -330,16 +296,10 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
+ struct device *dev = &pdev->dev;
+ struct device_node *np = pdev->dev.of_node;
+ struct rk3399_dmcfreq *data;
+- int ret, irq, index, size;
++ int ret, index, size;
+ uint32_t *timing;
+ struct dev_pm_opp *opp;
+
+- irq = platform_get_irq(pdev, 0);
+- if (irq < 0) {
+- dev_err(&pdev->dev,
+- "Cannot get the dmc interrupt resource: %d\n", irq);
+- return irq;
+- }
+ data = devm_kzalloc(dev, sizeof(struct rk3399_dmcfreq), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+@@ -358,17 +318,6 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
+ return PTR_ERR(data->dmc_clk);
+ };
+
+- data->irq = irq;
+- ret = devm_request_irq(dev, irq, rk3399_dmc_irq, 0,
+- dev_name(dev), data);
+- if (ret) {
+- dev_err(dev, "Failed to request dmc irq: %d\n", ret);
+- return ret;
+- }
+-
+- init_waitqueue_head(&data->wait_dcf_queue);
+- data->wait_dcf_flag = 0;
+-
+ data->edev = devfreq_event_get_edev_by_phandle(dev, 0);
+ if (IS_ERR(data->edev))
+ return -EPROBE_DEFER;
+--
+2.11.0
+
diff --git a/patches.drivers/0008-PM-devfreq-rk3399_dmc-do-not-print-error-when-get-su.patch b/patches.drivers/0008-PM-devfreq-rk3399_dmc-do-not-print-error-when-get-su.patch
new file mode 100644
index 0000000000..d7da930186
--- /dev/null
+++ b/patches.drivers/0008-PM-devfreq-rk3399_dmc-do-not-print-error-when-get-su.patch
@@ -0,0 +1,48 @@
+From: Lin Huang <hl@rock-chips.com>
+Date: Wed, 9 May 2018 14:57:47 +0200
+Subject: PM / devfreq: rk3399_dmc: do not print error when get supply and clk
+ defer.
+
+Git-commit: 49edc52312c34c981722833b0d9344c2aa83892d
+Patch-mainline: v4.19-rc1
+References: bsc#1144718,bsc#1144813
+
+We just return -EPROBE_DEFER error code to caller and do not
+print error message when try to get center logic regulator
+and DMC clock defer.
+
+Signed-off-by: Lin Huang <hl@rock-chips.com>
+Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/devfreq/rk3399_dmc.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
+index 44a379657cd5..5bfca028eaaf 100644
+--- a/drivers/devfreq/rk3399_dmc.c
++++ b/drivers/devfreq/rk3399_dmc.c
+@@ -308,12 +308,18 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
+
+ data->vdd_center = devm_regulator_get(dev, "center");
+ if (IS_ERR(data->vdd_center)) {
++ if (PTR_ERR(data->vdd_center) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++
+ dev_err(dev, "Cannot get the regulator \"center\"\n");
+ return PTR_ERR(data->vdd_center);
+ }
+
+ data->dmc_clk = devm_clk_get(dev, "dmc_clk");
+ if (IS_ERR(data->dmc_clk)) {
++ if (PTR_ERR(data->dmc_clk) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++
+ dev_err(dev, "Cannot get the clk dmc_clk\n");
+ return PTR_ERR(data->dmc_clk);
+ };
+--
+2.11.0
+
diff --git a/patches.drivers/0009-PM-devfreq-rk3399_dmc-fix-spelling-mistakes.patch b/patches.drivers/0009-PM-devfreq-rk3399_dmc-fix-spelling-mistakes.patch
new file mode 100644
index 0000000000..0f7d843400
--- /dev/null
+++ b/patches.drivers/0009-PM-devfreq-rk3399_dmc-fix-spelling-mistakes.patch
@@ -0,0 +1,64 @@
+From: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Date: Wed, 9 May 2018 14:57:48 +0200
+Subject: PM / devfreq: rk3399_dmc: fix spelling mistakes.
+
+Git-commit: dfa7d764caf00b12da276ea473d7f1fd7fd40200
+Patch-mainline: v4.19-rc1
+References: bsc#1144718,bsc#1144813
+
+Fix some spelling mistakes in error and debug messages.
+
+Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/devfreq/rk3399_dmc.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
+index 5bfca028eaaf..d5c03e5abe13 100644
+--- a/drivers/devfreq/rk3399_dmc.c
++++ b/drivers/devfreq/rk3399_dmc.c
+@@ -103,7 +103,7 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+ err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,
+ target_volt);
+ if (err) {
+- dev_err(dev, "Cannot to set voltage %lu uV\n",
++ dev_err(dev, "Cannot set voltage %lu uV\n",
+ target_volt);
+ goto out;
+ }
+@@ -111,8 +111,8 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+
+ err = clk_set_rate(dmcfreq->dmc_clk, target_rate);
+ if (err) {
+- dev_err(dev, "Cannot to set frequency %lu (%d)\n",
+- target_rate, err);
++ dev_err(dev, "Cannot set frequency %lu (%d)\n", target_rate,
++ err);
+ regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,
+ dmcfreq->volt);
+ goto out;
+@@ -128,8 +128,8 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+
+ /* If get the incorrect rate, set voltage to old value. */
+ if (dmcfreq->rate != target_rate) {
+- dev_err(dev, "Get wrong ddr frequency, Request frequency %lu,\
+- Current frequency %lu\n", target_rate, dmcfreq->rate);
++ dev_err(dev, "Got wrong frequency, Request %lu, Current %lu\n",
++ target_rate, dmcfreq->rate);
+ regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,
+ dmcfreq->volt);
+ goto out;
+@@ -137,7 +137,7 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+ err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,
+ target_volt);
+ if (err)
+- dev_err(dev, "Cannot to set vol %lu uV\n", target_volt);
++ dev_err(dev, "Cannot set voltage %lu uV\n", target_volt);
+
+ dmcfreq->rate = target_rate;
+ dmcfreq->volt = target_volt;
+--
+2.11.0
+
diff --git a/patches.drivers/0010-PM-devfreq-rk3399_dmc-remove-unneeded-semicolon.patch b/patches.drivers/0010-PM-devfreq-rk3399_dmc-remove-unneeded-semicolon.patch
new file mode 100644
index 0000000000..e9ef68395f
--- /dev/null
+++ b/patches.drivers/0010-PM-devfreq-rk3399_dmc-remove-unneeded-semicolon.patch
@@ -0,0 +1,34 @@
+From: Yangtao Li <tiny.windzz@gmail.com>
+Date: Sat, 16 Feb 2019 10:18:24 -0500
+Subject: PM / devfreq: rk3399_dmc: remove unneeded semicolon
+
+Git-commit: e2794d74f1ec6d31e662b147d55041bd00277278
+Patch-mainline: v5.2-rc1
+References: bsc#1144718,bsc#1144813
+
+The semicolon is unneeded, so remove it.
+
+Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
+Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/devfreq/rk3399_dmc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
+index e795ad2b3f6b..a228dad2bee4 100644
+--- a/drivers/devfreq/rk3399_dmc.c
++++ b/drivers/devfreq/rk3399_dmc.c
+@@ -322,7 +322,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
+
+ dev_err(dev, "Cannot get the clk dmc_clk\n");
+ return PTR_ERR(data->dmc_clk);
+- };
++ }
+
+ data->edev = devfreq_event_get_edev_by_phandle(dev, 0);
+ if (IS_ERR(data->edev))
+--
+2.11.0
+
diff --git a/patches.drivers/0011-PM-devfreq-rockchip-dfi-Move-GRF-definitions-to-a-co.patch b/patches.drivers/0011-PM-devfreq-rockchip-dfi-Move-GRF-definitions-to-a-co.patch
new file mode 100644
index 0000000000..c572d93e6e
--- /dev/null
+++ b/patches.drivers/0011-PM-devfreq-rockchip-dfi-Move-GRF-definitions-to-a-co.patch
@@ -0,0 +1,110 @@
+From: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Date: Thu, 21 Mar 2019 19:14:36 -0400
+Subject: PM / devfreq: rockchip-dfi: Move GRF definitions to a common place.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Git-commit: adfe3b76608ffe547af5a74415f15499b798f32a
+Patch-mainline: v5.2-rc1
+References: bsc#1144718,bsc#1144813
+
+Some rk3399 GRF (Generic Register Files) definitions can be used for
+different drivers. Move these definitions to a common include so we
+don't need to duplicate these definitions.
+
+Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Gaël PORTAY <gael.portay@collabora.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/devfreq/event/rockchip-dfi.c | 23 +++++++----------------
+ include/soc/rockchip/rk3399_grf.h | 21 +++++++++++++++++++++
+ 2 files changed, 28 insertions(+), 16 deletions(-)
+ create mode 100644 include/soc/rockchip/rk3399_grf.h
+
+diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
+index fcbf76ebf55d..a436ec4901bb 100644
+--- a/drivers/devfreq/event/rockchip-dfi.c
++++ b/drivers/devfreq/event/rockchip-dfi.c
+@@ -26,6 +26,8 @@
+ #include <linux/list.h>
+ #include <linux/of.h>
+
++#include <soc/rockchip/rk3399_grf.h>
++
+ #define RK3399_DMC_NUM_CH 2
+
+ /* DDRMON_CTRL */
+@@ -43,18 +45,6 @@
+ #define DDRMON_CH1_COUNT_NUM 0x3c
+ #define DDRMON_CH1_DFI_ACCESS_NUM 0x40
+
+-/* pmu grf */
+-#define PMUGRF_OS_REG2 0x308
+-#define DDRTYPE_SHIFT 13
+-#define DDRTYPE_MASK 7
+-
+-enum {
+- DDR3 = 3,
+- LPDDR3 = 6,
+- LPDDR4 = 7,
+- UNUSED = 0xFF
+-};
+-
+ struct dmc_usage {
+ u32 access;
+ u32 total;
+@@ -83,16 +73,17 @@ static void rockchip_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
+ u32 ddr_type;
+
+ /* get ddr type */
+- regmap_read(info->regmap_pmu, PMUGRF_OS_REG2, &val);
+- ddr_type = (val >> DDRTYPE_SHIFT) & DDRTYPE_MASK;
++ regmap_read(info->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
++ ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
++ RK3399_PMUGRF_DDRTYPE_MASK;
+
+ /* clear DDRMON_CTRL setting */
+ writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL);
+
+ /* set ddr type to dfi */
+- if (ddr_type == LPDDR3)
++ if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR3)
+ writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL);
+- else if (ddr_type == LPDDR4)
++ else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR4)
+ writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL);
+
+ /* enable count, use software mode */
+diff --git a/include/soc/rockchip/rk3399_grf.h b/include/soc/rockchip/rk3399_grf.h
+new file mode 100644
+index 000000000000..3eebabcb2812
+--- /dev/null
++++ b/include/soc/rockchip/rk3399_grf.h
+@@ -0,0 +1,21 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++/*
++ * Rockchip General Register Files definitions
++ *
++ * Copyright (c) 2018, Collabora Ltd.
++ * Author: Enric Balletbo i Serra <enric.balletbo@collabora.com>
++ */
++
++#ifndef __SOC_RK3399_GRF_H
++#define __SOC_RK3399_GRF_H
++
++/* PMU GRF Registers */
++#define RK3399_PMUGRF_OS_REG2 0x308
++#define RK3399_PMUGRF_DDRTYPE_SHIFT 13
++#define RK3399_PMUGRF_DDRTYPE_MASK 7
++#define RK3399_PMUGRF_DDRTYPE_DDR3 3
++#define RK3399_PMUGRF_DDRTYPE_LPDDR2 5
++#define RK3399_PMUGRF_DDRTYPE_LPDDR3 6
++#define RK3399_PMUGRF_DDRTYPE_LPDDR4 7
++
++#endif
+--
+2.11.0
+
diff --git a/patches.drivers/0012-PM-devfreq-rk3399_dmc-Pass-ODT-and-auto-power-down-p.patch b/patches.drivers/0012-PM-devfreq-rk3399_dmc-Pass-ODT-and-auto-power-down-p.patch
new file mode 100644
index 0000000000..7c22d14dbb
--- /dev/null
+++ b/patches.drivers/0012-PM-devfreq-rk3399_dmc-Pass-ODT-and-auto-power-down-p.patch
@@ -0,0 +1,178 @@
+From: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Date: Thu, 21 Mar 2019 19:14:38 -0400
+Subject: PM / devfreq: rk3399_dmc: Pass ODT and auto power down parameters to
+ TF-A.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Git-commit: 9173c5ceb035aab28171cd74dfddf27f47213b99
+Patch-mainline: v5.2-rc1
+References: bsc#1144718,bsc#1144813
+
+Trusted Firmware-A (TF-A) for rk3399 implements a SiP call to get the
+on-die termination (ODT) and auto power down parameters from kernel,
+this patch adds the functionality to do this. Also, if DDR clock
+frequency is lower than the on-die termination (ODT) disable frequency
+this driver should disable the DDR ODT.
+
+Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Gaël PORTAY <gael.portay@collabora.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
+---
+ drivers/devfreq/rk3399_dmc.c | 71 ++++++++++++++++++++++++++++++++++++-
+ include/soc/rockchip/rockchip_sip.h | 1 +
+ 2 files changed, 71 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
+index a228dad2bee4..567c034d0301 100644
+--- a/drivers/devfreq/rk3399_dmc.c
++++ b/drivers/devfreq/rk3399_dmc.c
+@@ -18,14 +18,17 @@
+ #include <linux/devfreq.h>
+ #include <linux/devfreq-event.h>
+ #include <linux/interrupt.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_opp.h>
++#include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/rwsem.h>
+ #include <linux/suspend.h>
+
++#include <soc/rockchip/rk3399_grf.h>
+ #include <soc/rockchip/rockchip_sip.h>
+
+ struct dram_timing {
+@@ -69,8 +72,11 @@ struct rk3399_dmcfreq {
+ struct mutex lock;
+ struct dram_timing timing;
+ struct regulator *vdd_center;
++ struct regmap *regmap_pmu;
+ unsigned long rate, target_rate;
+ unsigned long volt, target_volt;
++ unsigned int odt_dis_freq;
++ int odt_pd_arg0, odt_pd_arg1;
+ };
+
+ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+@@ -80,6 +86,8 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+ struct dev_pm_opp *opp;
+ unsigned long old_clk_rate = dmcfreq->rate;
+ unsigned long target_volt, target_rate;
++ struct arm_smccc_res res;
++ bool odt_enable = false;
+ int err;
+
+ opp = devfreq_recommended_opp(dev, freq, flags);
+@@ -95,6 +103,19 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+
+ mutex_lock(&dmcfreq->lock);
+
++ if (target_rate >= dmcfreq->odt_dis_freq)
++ odt_enable = true;
++
++ /*
++ * This makes a SMC call to the TF-A to set the DDR PD (power-down)
++ * timings and to enable or disable the ODT (on-die termination)
++ * resistors.
++ */
++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
++ dmcfreq->odt_pd_arg1,
++ ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
++ odt_enable, 0, 0, 0, &res);
++
+ /*
+ * If frequency scaling from low to high, adjust voltage first.
+ * If frequency scaling from high to low, adjust frequency first.
+@@ -294,11 +315,13 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
+ {
+ struct arm_smccc_res res;
+ struct device *dev = &pdev->dev;
+- struct device_node *np = pdev->dev.of_node;
++ struct device_node *np = pdev->dev.of_node, *node;
+ struct rk3399_dmcfreq *data;
+ int ret, index, size;
+ uint32_t *timing;
+ struct dev_pm_opp *opp;
++ u32 ddr_type;
++ u32 val;
+
+ data = devm_kzalloc(dev, sizeof(struct rk3399_dmcfreq), GFP_KERNEL);
+ if (!data)
+@@ -354,11 +377,57 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
+ }
+ }
+
++ node = of_parse_phandle(np, "rockchip,pmu", 0);
++ if (node) {
++ data->regmap_pmu = syscon_node_to_regmap(node);
++ if (IS_ERR(data->regmap_pmu))
++ return PTR_ERR(data->regmap_pmu);
++ }
++
++ regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
++ ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
++ RK3399_PMUGRF_DDRTYPE_MASK;
++
++ switch (ddr_type) {
++ case RK3399_PMUGRF_DDRTYPE_DDR3:
++ data->odt_dis_freq = data->timing.ddr3_odt_dis_freq;
++ break;
++ case RK3399_PMUGRF_DDRTYPE_LPDDR3:
++ data->odt_dis_freq = data->timing.lpddr3_odt_dis_freq;
++ break;
++ case RK3399_PMUGRF_DDRTYPE_LPDDR4:
++ data->odt_dis_freq = data->timing.lpddr4_odt_dis_freq;
++ break;
++ default:
++ return -EINVAL;
++ };
++
+ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
+ ROCKCHIP_SIP_CONFIG_DRAM_INIT,
+ 0, 0, 0, 0, &res);
+
+ /*
++ * In TF-A there is a platform SIP call to set the PD (power-down)
++ * timings and to enable or disable the ODT (on-die termination).
++ * This call needs three arguments as follows:
++ *
++ * arg0:
++ * bit[0-7] : sr_idle
++ * bit[8-15] : sr_mc_gate_idle
++ * bit[16-31] : standby idle
++ * arg1:
++ * bit[0-11] : pd_idle
++ * bit[16-27] : srpd_lite_idle
++ * arg2:
++ * bit[0] : odt enable
++ */
++ data->odt_pd_arg0 = (data->timing.sr_idle & 0xff) |
++ ((data->timing.sr_mc_gate_idle & 0xff) << 8) |
++ ((data->timing.standby_idle & 0xffff) << 16);
++ data->odt_pd_arg1 = (data->timing.pd_idle & 0xfff) |
++ ((data->timing.srpd_lite_idle & 0xfff) << 16);
++
++ /*
+ * We add a devfreq driver to our parent since it has a device tree node
+ * with operating points.
+ */
+diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
+index 7e28092c4d3d..ad9482c56797 100644
+--- a/include/soc/rockchip/rockchip_sip.h
++++ b/include/soc/rockchip/rockchip_sip.h
+@@ -23,5 +23,6 @@
+ #define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE 0x05
+ #define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06
+ #define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07
++#define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD 0x08
+
+ #endif
+--
+2.11.0
+
diff --git a/patches.drivers/clk-bcm2835-remove-pllb.patch b/patches.drivers/clk-bcm2835-remove-pllb.patch
new file mode 100644
index 0000000000..89fb673a95
--- /dev/null
+++ b/patches.drivers/clk-bcm2835-remove-pllb.patch
@@ -0,0 +1,57 @@
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Wed, 12 Jun 2019 20:24:53 +0200
+Subject: clk: bcm2835: remove pllb
+Git-commit: 2256d89333bd17b8b56b42734a7e1046d52f7fc3
+Patch-mainline: v5.3-rc1
+References: jsc#SLE-7294
+
+Raspberry Pi's firmware controls this pll, we should use the firmware
+interface to access it.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Acked-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/bcm/clk-bcm2835.c | 28 ++++------------------------
+ 1 file changed, 4 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
+index 770bb01f523e..867ae3c20041 100644
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1651,30 +1651,10 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
+ .fixed_divider = 1,
+ .flags = CLK_SET_RATE_PARENT),
+
+- /* PLLB is used for the ARM's clock. */
+- [BCM2835_PLLB] = REGISTER_PLL(
+- .name = "pllb",
+- .cm_ctrl_reg = CM_PLLB,
+- .a2w_ctrl_reg = A2W_PLLB_CTRL,
+- .frac_reg = A2W_PLLB_FRAC,
+- .ana_reg_base = A2W_PLLB_ANA0,
+- .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
+- .lock_mask = CM_LOCK_FLOCKB,
+-
+- .ana = &bcm2835_ana_default,
+-
+- .min_rate = 600000000u,
+- .max_rate = 3000000000u,
+- .max_fb_rate = BCM2835_MAX_FB_RATE),
+- [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV(
+- .name = "pllb_arm",
+- .source_pll = "pllb",
+- .cm_reg = CM_PLLB,
+- .a2w_reg = A2W_PLLB_ARM,
+- .load_mask = CM_PLLB_LOADARM,
+- .hold_mask = CM_PLLB_HOLDARM,
+- .fixed_divider = 1,
+- .flags = CLK_SET_RATE_PARENT),
++ /*
++ * PLLB is used for the ARM's clock. Controlled by firmware, see
++ * clk-raspberrypi.c.
++ */
+
+ /*
+ * PLLC is the core PLL, used to drive the core VPU clock.
+
diff --git a/patches.drivers/clk-bcm283x-add-driver-interfacing-with-raspberry-pi-s-firmware.patch b/patches.drivers/clk-bcm283x-add-driver-interfacing-with-raspberry-pi-s-firmware.patch
new file mode 100644
index 0000000000..0f21807b7b
--- /dev/null
+++ b/patches.drivers/clk-bcm283x-add-driver-interfacing-with-raspberry-pi-s-firmware.patch
@@ -0,0 +1,347 @@
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Wed, 12 Jun 2019 20:24:54 +0200
+Subject: clk: bcm283x: add driver interfacing with Raspberry Pi's firmware
+Git-commit: 4e85e535e6cc6e8a96350e8ee684d0f22eb8629e
+Patch-mainline: v5.3-rc1
+References: jsc#SLE-7294
+
+Raspberry Pi's firmware offers an interface though which update it's
+clock's frequencies. This is specially useful in order to change the CPU
+clock (pllb_arm) which is 'owned' by the firmware and we're unable to
+scale using the register interface provided by clk-bcm2835.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Acked-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/bcm/Kconfig | 7
+ drivers/clk/bcm/Makefile | 1
+ drivers/clk/bcm/clk-raspberrypi.c | 300 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 308 insertions(+)
+
+--- a/drivers/clk/bcm/Kconfig
++++ b/drivers/clk/bcm/Kconfig
+@@ -46,3 +46,10 @@ config CLK_BCM_NS2
+ default ARCH_BCM_IPROC
+ help
+ Enable common clock framework support for the Broadcom Northstar 2 SoC
++
++config CLK_RASPBERRYPI
++ tristate "Raspberry Pi firmware based clock support"
++ depends on RASPBERRYPI_FIRMWARE || (COMPILE_TEST && !RASPBERRYPI_FIRMWARE)
++ help
++ Enable common clock framework support for Raspberry Pi's firmware
++ dependent clocks
+--- a/drivers/clk/bcm/Makefile
++++ b/drivers/clk/bcm/Makefile
+@@ -7,6 +7,7 @@ obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ip
+ obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
+ obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o
+ obj-$(CONFIG_ARCH_BCM_53573) += clk-bcm53573-ilp.o
++obj-$(CONFIG_CLK_RASPBERRYPI) += clk-raspberrypi.o
+ obj-$(CONFIG_CLK_BCM_CYGNUS) += clk-cygnus.o
+ obj-$(CONFIG_CLK_BCM_NSP) += clk-nsp.o
+ obj-$(CONFIG_CLK_BCM_NS2) += clk-ns2.o
+--- /dev/null
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -0,0 +1,300 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Raspberry Pi driver for firmware controlled clocks
++ *
++ * Even though clk-bcm2835 provides an interface to the hardware registers for
++ * the system clocks we've had to factor out 'pllb' as the firmware 'owns' it.
++ * We're not allowed to change it directly as we might race with the
++ * over-temperature and under-voltage protections provided by the firmware.
++ *
++ * Copyright (C) 2019 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
++ */
++
++#include <linux/clkdev.h>
++#include <linux/clk-provider.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <soc/bcm2835/raspberrypi-firmware.h>
++
++#define RPI_FIRMWARE_ARM_CLK_ID 0x00000003
++
++#define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
++#define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1)
++
++/*
++ * Even though the firmware interface alters 'pllb' the frequencies are
++ * provided as per 'pllb_arm'. We need to scale before passing them trough.
++ */
++#define RPI_FIRMWARE_PLLB_ARM_DIV_RATE 2
++
++#define A2W_PLL_FRAC_BITS 20
++
++struct raspberrypi_clk {
++ struct device *dev;
++ struct rpi_firmware *firmware;
++
++ unsigned long min_rate;
++ unsigned long max_rate;
++
++ struct clk_hw pllb;
++ struct clk_hw *pllb_arm;
++ struct clk_lookup *pllb_arm_lookup;
++};
++
++/*
++ * Structure of the message passed to Raspberry Pi's firmware in order to
++ * change clock rates. The 'disable_turbo' option is only available to the ARM
++ * clock (pllb) which we enable by default as turbo mode will alter multiple
++ * clocks at once.
++ *
++ * Even though we're able to access the clock registers directly we're bound to
++ * use the firmware interface as the firmware ultimately takes care of
++ * mitigating overheating/undervoltage situations and we would be changing
++ * frequencies behind his back.
++ *
++ * For more information on the firmware interface check:
++ * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
++ */
++struct raspberrypi_firmware_prop {
++ __le32 id;
++ __le32 val;
++ __le32 disable_turbo;
++} __packed;
++
++static int raspberrypi_clock_property(struct rpi_firmware *firmware, u32 tag,
++ u32 clk, u32 *val)
++{
++ struct raspberrypi_firmware_prop msg = {
++ .id = cpu_to_le32(clk),
++ .val = cpu_to_le32(*val),
++ .disable_turbo = cpu_to_le32(1),
++ };
++ int ret;
++
++ ret = rpi_firmware_property(firmware, tag, &msg, sizeof(msg));
++ if (ret)
++ return ret;
++
++ *val = le32_to_cpu(msg.val);
++
++ return 0;
++}
++
++static int raspberrypi_fw_pll_is_on(struct clk_hw *hw)
++{
++ struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
++ pllb);
++ u32 val = 0;
++ int ret;
++
++ ret = raspberrypi_clock_property(rpi->firmware,
++ RPI_FIRMWARE_GET_CLOCK_STATE,
++ RPI_FIRMWARE_ARM_CLK_ID, &val);
++ if (ret)
++ return 0;
++
++ return !!(val & RPI_FIRMWARE_STATE_ENABLE_BIT);
++}
++
++
++static unsigned long raspberrypi_fw_pll_get_rate(struct clk_hw *hw,
++ unsigned long parent_rate)
++{
++ struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
++ pllb);
++ u32 val = 0;
++ int ret;
++
++ ret = raspberrypi_clock_property(rpi->firmware,
++ RPI_FIRMWARE_GET_CLOCK_RATE,
++ RPI_FIRMWARE_ARM_CLK_ID,
++ &val);
++ if (ret)
++ return ret;
++
++ return val * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
++}
++
++static int raspberrypi_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long parent_rate)
++{
++ struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
++ pllb);
++ u32 new_rate = rate / RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
++ int ret;
++
++ ret = raspberrypi_clock_property(rpi->firmware,
++ RPI_FIRMWARE_SET_CLOCK_RATE,
++ RPI_FIRMWARE_ARM_CLK_ID,
++ &new_rate);
++ if (ret)
++ dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d",
++ clk_hw_get_name(hw), ret);
++
++ return ret;
++}
++
++/*
++ * Sadly there is no firmware rate rounding interface. We borrowed it from
++ * clk-bcm2835.
++ */
++static int raspberrypi_pll_determine_rate(struct clk_hw *hw,
++ struct clk_rate_request *req)
++{
++ struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
++ pllb);
++ u64 div, final_rate;
++ u32 ndiv, fdiv;
++
++ /* We can't use req->rate directly as it would overflow */
++ final_rate = clamp(req->rate, rpi->min_rate, rpi->max_rate);
++
++ div = (u64)final_rate << A2W_PLL_FRAC_BITS;
++ do_div(div, req->best_parent_rate);
++
++ ndiv = div >> A2W_PLL_FRAC_BITS;
++ fdiv = div & ((1 << A2W_PLL_FRAC_BITS) - 1);
++
++ final_rate = ((u64)req->best_parent_rate *
++ ((ndiv << A2W_PLL_FRAC_BITS) + fdiv));
++
++ req->rate = final_rate >> A2W_PLL_FRAC_BITS;
++
++ return 0;
++}
++
++static const struct clk_ops raspberrypi_firmware_pll_clk_ops = {
++ .is_prepared = raspberrypi_fw_pll_is_on,
++ .recalc_rate = raspberrypi_fw_pll_get_rate,
++ .set_rate = raspberrypi_fw_pll_set_rate,
++ .determine_rate = raspberrypi_pll_determine_rate,
++};
++
++static int raspberrypi_register_pllb(struct raspberrypi_clk *rpi)
++{
++ u32 min_rate = 0, max_rate = 0;
++ struct clk_init_data init;
++ int ret;
++
++ memset(&init, 0, sizeof(init));
++
++ /* All of the PLLs derive from the external oscillator. */
++ init.parent_names = (const char *[]){ "osc" };
++ init.num_parents = 1;
++ init.name = "pllb";
++ init.ops = &raspberrypi_firmware_pll_clk_ops;
++ init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED;
++
++ /* Get min & max rates set by the firmware */
++ ret = raspberrypi_clock_property(rpi->firmware,
++ RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
++ RPI_FIRMWARE_ARM_CLK_ID,
++ &min_rate);
++ if (ret) {
++ dev_err(rpi->dev, "Failed to get %s min freq: %d\n",
++ init.name, ret);
++ return ret;
++ }
++
++ ret = raspberrypi_clock_property(rpi->firmware,
++ RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
++ RPI_FIRMWARE_ARM_CLK_ID,
++ &max_rate);
++ if (ret) {
++ dev_err(rpi->dev, "Failed to get %s max freq: %d\n",
++ init.name, ret);
++ return ret;
++ }
++
++ if (!min_rate || !max_rate) {
++ dev_err(rpi->dev, "Unexpected frequency range: min %u, max %u\n",
++ min_rate, max_rate);
++ return -EINVAL;
++ }
++
++ dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n",
++ min_rate, max_rate);
++
++ rpi->min_rate = min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
++ rpi->max_rate = max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
++
++ rpi->pllb.init = &init;
++
++ return devm_clk_hw_register(rpi->dev, &rpi->pllb);
++}
++
++static int raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi)
++{
++ rpi->pllb_arm = clk_hw_register_fixed_factor(rpi->dev,
++ "pllb_arm", "pllb",
++ CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
++ 1, 2);
++ if (IS_ERR(rpi->pllb_arm)) {
++ dev_err(rpi->dev, "Failed to initialize pllb_arm\n");
++ return PTR_ERR(rpi->pllb_arm);
++ }
++
++ rpi->pllb_arm_lookup = clkdev_hw_create(rpi->pllb_arm, NULL, "cpu0");
++ if (!rpi->pllb_arm_lookup) {
++ dev_err(rpi->dev, "Failed to initialize pllb_arm_lookup\n");
++ clk_hw_unregister_fixed_factor(rpi->pllb_arm);
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++static int raspberrypi_clk_probe(struct platform_device *pdev)
++{
++ struct device_node *firmware_node;
++ struct device *dev = &pdev->dev;
++ struct rpi_firmware *firmware;
++ struct raspberrypi_clk *rpi;
++ int ret;
++
++ firmware_node = of_find_compatible_node(NULL, NULL,
++ "raspberrypi,bcm2835-firmware");
++ if (!firmware_node) {
++ dev_err(dev, "Missing firmware node\n");
++ return -ENOENT;
++ }
++
++ firmware = rpi_firmware_get(firmware_node);
++ of_node_put(firmware_node);
++ if (!firmware)
++ return -EPROBE_DEFER;
++
++ rpi = devm_kzalloc(dev, sizeof(*rpi), GFP_KERNEL);
++ if (!rpi)
++ return -ENOMEM;
++
++ rpi->dev = dev;
++ rpi->firmware = firmware;
++
++ ret = raspberrypi_register_pllb(rpi);
++ if (ret) {
++ dev_err(dev, "Failed to initialize pllb, %d\n", ret);
++ return ret;
++ }
++
++ ret = raspberrypi_register_pllb_arm(rpi);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++static struct platform_driver raspberrypi_clk_driver = {
++ .driver = {
++ .name = "raspberrypi-clk",
++ },
++ .probe = raspberrypi_clk_probe,
++};
++module_platform_driver(raspberrypi_clk_driver);
++
++MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>");
++MODULE_DESCRIPTION("Raspberry Pi firmware clock driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:raspberrypi-clk");
diff --git a/patches.drivers/clk-raspberrypi-register-platform-device-for-raspberrypi-cpufreq.patch b/patches.drivers/clk-raspberrypi-register-platform-device-for-raspberrypi-cpufreq.patch
new file mode 100644
index 0000000000..4ee3539302
--- /dev/null
+++ b/patches.drivers/clk-raspberrypi-register-platform-device-for-raspberrypi-cpufreq.patch
@@ -0,0 +1,67 @@
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Wed, 12 Jun 2019 20:24:57 +0200
+Subject: clk: raspberrypi: register platform device for raspberrypi-cpufreq
+Git-commit: e2bb18347c8e5c4187831f3700c380e3c759601a
+Patch-mainline: v5.3-rc1
+References: jsc#SLE-7294
+
+As 'clk-raspberrypi' depends on RPi's firmware interface, which might be
+configured as a module, the cpu clock might not be available for the
+cpufreq driver during it's init process. So we register the
+'raspberrypi-cpufreq' platform device after the probe sequence succeeds.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Acked-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
+index fef1f7caee4f..1654fd0eedc9 100644
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -34,6 +34,7 @@
+ struct raspberrypi_clk {
+ struct device *dev;
+ struct rpi_firmware *firmware;
++ struct platform_device *cpufreq;
+
+ unsigned long min_rate;
+ unsigned long max_rate;
+@@ -272,6 +273,7 @@ static int raspberrypi_clk_probe(struct platform_device *pdev)
+
+ rpi->dev = dev;
+ rpi->firmware = firmware;
++ platform_set_drvdata(pdev, rpi);
+
+ ret = raspberrypi_register_pllb(rpi);
+ if (ret) {
+@@ -283,6 +285,18 @@ static int raspberrypi_clk_probe(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
++ rpi->cpufreq = platform_device_register_data(dev, "raspberrypi-cpufreq",
++ -1, NULL, 0);
++
++ return 0;
++}
++
++static int raspberrypi_clk_remove(struct platform_device *pdev)
++{
++ struct raspberrypi_clk *rpi = platform_get_drvdata(pdev);
++
++ platform_device_unregister(rpi->cpufreq);
++
+ return 0;
+ }
+
+@@ -291,6 +305,7 @@ static struct platform_driver raspberrypi_clk_driver = {
+ .name = "raspberrypi-clk",
+ },
+ .probe = raspberrypi_clk_probe,
++ .remove = raspberrypi_clk_remove,
+ };
+ module_platform_driver(raspberrypi_clk_driver);
+
+
diff --git a/patches.drivers/cpufreq-add-driver-for-raspberry-pi.patch b/patches.drivers/cpufreq-add-driver-for-raspberry-pi.patch
new file mode 100644
index 0000000000..757eb03d52
--- /dev/null
+++ b/patches.drivers/cpufreq-add-driver-for-raspberry-pi.patch
@@ -0,0 +1,179 @@
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Wed, 12 Jun 2019 20:24:56 +0200
+Subject: cpufreq: add driver for Raspberry Pi
+Git-commit: d3df18a97e586702920337056540267807b23f8e
+Patch-mainline: v5.3-rc1
+References: jsc#SLE-7294
+
+Raspberry Pi's firmware offers and interface though which update it's
+performance requirements. It allows us to request for specific runtime
+frequencies, which the firmware might or might not respect, depending on
+the firmware configuration and thermals.
+
+As the maximum and minimum frequencies are configurable in the firmware
+there is no way to know in advance their values. So the Raspberry Pi
+cpufreq driver queries them, builds an opp frequency table to then
+launch cpufreq-dt.
+
+Also, as the firmware interface might be configured as a module, making
+the cpu clock unavailable during init, this implements a full fledged
+driver, as opposed to most drivers registering cpufreq-dt, which only
+make use of an init routine.
+
+NOTE: I added a change in cpufreq-dt which is somewhat dirty, but it's way
+better that the mess that would have been backporting the feature needed for
+ondemand to work with raspberrypi-cpufreq without breaking kABI (I actually
+think it's impssible).
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Acked-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/Kconfig.arm | 8 ++
+ drivers/cpufreq/Makefile | 1
+ drivers/cpufreq/cpufreq-dt.c | 4 +
+ drivers/cpufreq/raspberrypi-cpufreq.c | 97 ++++++++++++++++++++++++++++++++++
+ 4 files changed, 110 insertions(+)
+
+--- a/drivers/cpufreq/Kconfig.arm
++++ b/drivers/cpufreq/Kconfig.arm
+@@ -110,6 +110,14 @@ config ARM_OMAP2PLUS_CPUFREQ
+ depends on ARCH_OMAP2PLUS
+ default ARCH_OMAP2PLUS
+
++config ARM_RASPBERRYPI_CPUFREQ
++ tristate "Raspberry Pi cpufreq support"
++ depends on CLK_RASPBERRYPI || COMPILE_TEST
++ help
++ This adds the CPUFreq driver for Raspberry Pi
++
++ If in doubt, say N.
++
+ config ARM_S3C_CPUFREQ
+ bool
+ help
+--- a/drivers/cpufreq/Makefile
++++ b/drivers/cpufreq/Makefile
+@@ -62,6 +62,7 @@ obj-$(CONFIG_ARM_MT8173_CPUFREQ) += mt81
+ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
+ obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
+ obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
++obj-$(CONFIG_ARM_RASPBERRYPI_CPUFREQ) += raspberrypi-cpufreq.o
+ obj-$(CONFIG_ARM_S3C24XX_CPUFREQ) += s3c24xx-cpufreq.o
+ obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o
+ obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o
+--- /dev/null
++++ b/drivers/cpufreq/raspberrypi-cpufreq.c
+@@ -0,0 +1,97 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Raspberry Pi cpufreq driver
++ *
++ * Copyright (C) 2019, Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
++ */
++
++#include <linux/clk.h>
++#include <linux/cpu.h>
++#include <linux/cpufreq.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/pm_opp.h>
++
++#define RASPBERRYPI_FREQ_INTERVAL 100000000
++
++static struct platform_device *cpufreq_dt;
++
++static int raspberrypi_cpufreq_probe(struct platform_device *pdev)
++{
++ struct device *cpu_dev;
++ unsigned long min, max;
++ unsigned long rate;
++ struct clk *clk;
++ int ret;
++
++ cpu_dev = get_cpu_device(0);
++ if (!cpu_dev) {
++ pr_err("Cannot get CPU for cpufreq driver\n");
++ return -ENODEV;
++ }
++
++ clk = clk_get(cpu_dev, NULL);
++ if (IS_ERR(clk)) {
++ dev_err(cpu_dev, "Cannot get clock for CPU0\n");
++ return PTR_ERR(clk);
++ }
++
++ /*
++ * The max and min frequencies are configurable in the Raspberry Pi
++ * firmware, so we query them at runtime.
++ */
++ min = roundup(clk_round_rate(clk, 0), RASPBERRYPI_FREQ_INTERVAL);
++ max = roundup(clk_round_rate(clk, ULONG_MAX), RASPBERRYPI_FREQ_INTERVAL);
++ clk_put(clk);
++
++ for (rate = min; rate <= max; rate += RASPBERRYPI_FREQ_INTERVAL) {
++ ret = dev_pm_opp_add(cpu_dev, rate, 0);
++ if (ret)
++ goto remove_opp;
++ }
++
++ cpufreq_dt = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
++ ret = PTR_ERR_OR_ZERO(cpufreq_dt);
++ if (ret) {
++ dev_err(cpu_dev, "Failed to create platform device, %d\n", ret);
++ goto remove_opp;
++ }
++
++ return 0;
++
++remove_opp:
++ dev_pm_opp_remove_table(cpu_dev);
++
++ return ret;
++}
++
++static int raspberrypi_cpufreq_remove(struct platform_device *pdev)
++{
++ struct device *cpu_dev;
++
++ cpu_dev = get_cpu_device(0);
++ if (cpu_dev)
++ dev_pm_opp_remove_table(cpu_dev);
++
++ platform_device_unregister(cpufreq_dt);
++
++ return 0;
++}
++
++/*
++ * Since the driver depends on clk-raspberrypi, which may return EPROBE_DEFER,
++ * all the activity is performed in the probe, which may be defered as well.
++ */
++static struct platform_driver raspberrypi_cpufreq_driver = {
++ .driver = {
++ .name = "raspberrypi-cpufreq",
++ },
++ .probe = raspberrypi_cpufreq_probe,
++ .remove = raspberrypi_cpufreq_remove,
++};
++module_platform_driver(raspberrypi_cpufreq_driver);
++
++MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de");
++MODULE_DESCRIPTION("Raspberry Pi cpufreq driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:raspberrypi-cpufreq");
+--- a/drivers/cpufreq/cpufreq-dt.c
++++ b/drivers/cpufreq/cpufreq-dt.c
+@@ -273,6 +273,10 @@ static int cpufreq_init(struct cpufreq_p
+ if (!transition_latency)
+ transition_latency = CPUFREQ_ETERNAL;
+
++ if (of_machine_is_compatible("brcm,bcm2837") ||
++ of_machine_is_compatible("brcm,bcm2711"))
++ transition_latency = 335000;
++
+ policy->cpuinfo.transition_latency = transition_latency;
+
+ return 0;
diff --git a/patches.drivers/cpufreq-dt-try-freeing-static-opps-only-if-we-have-added-them.patch b/patches.drivers/cpufreq-dt-try-freeing-static-opps-only-if-we-have-added-them.patch
new file mode 100644
index 0000000000..3ef12f58fa
--- /dev/null
+++ b/patches.drivers/cpufreq-dt-try-freeing-static-opps-only-if-we-have-added-them.patch
@@ -0,0 +1,111 @@
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 3 Oct 2018 15:35:21 +0530
+Subject: cpufreq: dt: Try freeing static OPPs only if we have added them
+Git-commit: 51c99dd2c06b234575661fa1e0a1dea6c3ef566f
+Patch-mainline: v4.20-rc1
+References: jsc#SLE-7294
+
+We can not call dev_pm_opp_of_cpumask_remove_table() freely anymore
+since the latest OPP core updates as that uses reference counting to
+free resources. There are cases where no static OPPs are added (using
+DT) for a platform and trying to remove the OPP table may end up
+decrementing refcount which is already zero and hence generating
+warnings.
+
+Lets track if we were able to add static OPPs or not and then only
+remove the table based on that. Some reshuffling of code is also done to
+do that.
+
+Reported-by: Niklas Cassel <niklas.cassel@linaro.org>
+Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+---
+ drivers/cpufreq/cpufreq-dt.c | 34 +++++++++++++++++++---------------
+ 1 file changed, 19 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
+index 0a9ebf00be46..e58bfcb1169e 100644
+--- a/drivers/cpufreq/cpufreq-dt.c
++++ b/drivers/cpufreq/cpufreq-dt.c
+@@ -32,6 +32,7 @@ struct private_data {
+ struct device *cpu_dev;
+ struct thermal_cooling_device *cdev;
+ const char *reg_name;
++ bool have_static_opps;
+ };
+
+ static struct freq_attr *cpufreq_dt_attr[] = {
+@@ -204,6 +205,15 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+ }
+ }
+
++ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++ if (!priv) {
++ ret = -ENOMEM;
++ goto out_put_regulator;
++ }
++
++ priv->reg_name = name;
++ priv->opp_table = opp_table;
++
+ /*
+ * Initialize OPP tables for all policy->cpus. They will be shared by
+ * all CPUs which have marked their CPUs shared with OPP bindings.
+@@ -214,7 +224,8 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+ *
+ * OPPs might be populated at runtime, don't check for error here
+ */
+- dev_pm_opp_of_cpumask_add_table(policy->cpus);
++ if (!dev_pm_opp_of_cpumask_add_table(policy->cpus))
++ priv->have_static_opps = true;
+
+ /*
+ * But we need OPP table to function so if it is not there let's
+@@ -240,19 +251,10 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+ __func__, ret);
+ }
+
+- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+- if (!priv) {
+- ret = -ENOMEM;
+- goto out_free_opp;
+- }
+-
+- priv->reg_name = name;
+- priv->opp_table = opp_table;
+-
+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
+ if (ret) {
+ dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
+- goto out_free_priv;
++ goto out_free_opp;
+ }
+
+ priv->cpu_dev = cpu_dev;
+@@ -282,10 +284,11 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+
+ out_free_cpufreq_table:
+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
+-out_free_priv:
+- kfree(priv);
+ out_free_opp:
+- dev_pm_opp_of_cpumask_remove_table(policy->cpus);
++ if (priv->have_static_opps)
++ dev_pm_opp_of_cpumask_remove_table(policy->cpus);
++ kfree(priv);
++out_put_regulator:
+ if (name)
+ dev_pm_opp_put_regulators(opp_table);
+ out_put_clk:
+@@ -300,7 +303,8 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
+
+ cpufreq_cooling_unregister(priv->cdev);
+ dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
+- dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
++ if (priv->have_static_opps)
++ dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
+ if (priv->reg_name)
+ dev_pm_opp_put_regulators(priv->opp_table);
+
+
diff --git a/patches.drivers/firmware-raspberrypi-register-clk-device.patch b/patches.drivers/firmware-raspberrypi-register-clk-device.patch
new file mode 100644
index 0000000000..e4b5abd19c
--- /dev/null
+++ b/patches.drivers/firmware-raspberrypi-register-clk-device.patch
@@ -0,0 +1,60 @@
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Wed, 12 Jun 2019 20:24:55 +0200
+Subject: firmware: raspberrypi: register clk device
+Git-commit: 91f2cf4a6b2131016b1ae9c9500245f0572112c7
+Patch-mainline: v5.3-rc1
+References: jsc#SLE-7294
+
+Since clk-raspberrypi is tied to the VC4 firmware instead of particular
+hardware it's registration should be performed by the firmware driver.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Acked-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/firmware/raspberrypi.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
+index 61be15d9df7d..da26a584dca0 100644
+--- a/drivers/firmware/raspberrypi.c
++++ b/drivers/firmware/raspberrypi.c
+@@ -20,6 +20,7 @@
+ #define MBOX_CHAN_PROPERTY 8
+
+ static struct platform_device *rpi_hwmon;
++static struct platform_device *rpi_clk;
+
+ struct rpi_firmware {
+ struct mbox_client cl;
+@@ -207,6 +208,12 @@ rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw)
+ -1, NULL, 0);
+ }
+
++static void rpi_register_clk_driver(struct device *dev)
++{
++ rpi_clk = platform_device_register_data(dev, "raspberrypi-clk",
++ -1, NULL, 0);
++}
++
+ static int rpi_firmware_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -234,6 +241,7 @@ static int rpi_firmware_probe(struct platform_device *pdev)
+
+ rpi_firmware_print_firmware_revision(fw);
+ rpi_register_hwmon_driver(dev, fw);
++ rpi_register_clk_driver(dev);
+
+ return 0;
+ }
+@@ -254,6 +262,8 @@ static int rpi_firmware_remove(struct platform_device *pdev)
+
+ platform_device_unregister(rpi_hwmon);
+ rpi_hwmon = NULL;
++ platform_device_unregister(rpi_clk);
++ rpi_clk = NULL;
+ mbox_free_channel(fw->chan);
+
+ return 0;
+
diff --git a/patches.drivers/pm-opp-of-use-pr_debug-instead-of-pr_err-while-adding-opp-table.patch b/patches.drivers/pm-opp-of-use-pr_debug-instead-of-pr_err-while-adding-opp-table.patch
new file mode 100644
index 0000000000..967fdc395e
--- /dev/null
+++ b/patches.drivers/pm-opp-of-use-pr_debug-instead-of-pr_err-while-adding-opp-table.patch
@@ -0,0 +1,45 @@
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 12 Jul 2017 09:21:49 +0530
+Subject: PM / OPP: OF: Use pr_debug() instead of pr_err() while adding OPP
+ table
+Git-commit: 5b60697cd89cf5a438b2984e11859228e5ec1c6b
+Patch-mainline: v4.14-rc1
+References: jsc#SLE-7294
+
+Some platforms add the OPPs dynamically from platform specific drivers
+instead of getting them statically from DT. The cpufreq-dt driver
+already ignores the return value of dev_pm_opp_of_cpumask_add_table() to
+not error out for such cases, but we still end up printing error message
+from that routine. That's not nice.
+
+Convert the print message to use pr_debug() instead.
+
+Reported-by: Mason <slash.tmp@free.fr>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+---
+ drivers/base/power/opp/of.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/base/power/opp/of.c b/drivers/base/power/opp/of.c
+index 57eec1ca0569..6f0497b377c7 100644
+--- a/drivers/base/power/opp/of.c
++++ b/drivers/base/power/opp/of.c
+@@ -539,8 +539,12 @@ int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask)
+
+ ret = dev_pm_opp_of_add_table(cpu_dev);
+ if (ret) {
+- pr_err("%s: couldn't find opp table for cpu:%d, %d\n",
+- __func__, cpu, ret);
++ /*
++ * OPP may get registered dynamically, don't print error
++ * message here.
++ */
++ pr_debug("%s: couldn't find opp table for cpu:%d, %d\n",
++ __func__, cpu, ret);
+
+ /* Free all other OPPs */
+ dev_pm_opp_of_cpumask_remove_table(cpumask);
+
diff --git a/patches.drm/drm-i915-userptr-Acquire-the-page-lock-around-set_pa.patch b/patches.drm/drm-i915-userptr-Acquire-the-page-lock-around-set_pa.patch
new file mode 100644
index 0000000000..02b297e411
--- /dev/null
+++ b/patches.drm/drm-i915-userptr-Acquire-the-page-lock-around-set_pa.patch
@@ -0,0 +1,56 @@
+From aa56a292ce623734ddd30f52d73f527d1f3529b5 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Mon, 8 Jul 2019 15:03:27 +0100
+Subject: [PATCH] drm/i915/userptr: Acquire the page lock around set_page_dirty()
+Git-commit: aa56a292ce623734ddd30f52d73f527d1f3529b5
+Patch-mainline: v5.3-rc3
+No-fix: cb6d7c7dc7ff8cace666ddec66334117a6068ce2
+References: bsc#1051510
+
+set_page_dirty says:
+
+ For pages with a mapping this should be done under the page lock
+ for the benefit of asynchronous memory errors who prefer a
+ consistent dirty state. This rule can be broken in some special
+ cases, but should be better not to.
+
+Under those rules, it is only safe for us to use the plain set_page_dirty
+calls for shmemfs/anonymous memory. Userptr may be used with real
+mappings and so needs to use the locked version (set_page_dirty_lock).
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203317
+Fixes: 5cc9ed4b9a7a ("drm/i915: Introduce mapping of user pages into video memory (userptr) ioctl")
+References: 6dcc693bc57f ("ext4: warn when page is dirtied without buffers")
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20190708140327.26825-1-chris@chris-wilson.co.uk
+(cherry picked from commit cb6d7c7dc7ff8cace666ddec66334117a6068ce2)
+
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/gpu/drm/i915/i915_gem_userptr.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
++++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
+@@ -703,7 +703,15 @@ i915_gem_userptr_put_pages(struct drm_i9
+
+ for_each_sgt_page(page, sgt_iter, pages) {
+ if (obj->mm.dirty)
+- set_page_dirty(page);
++ /*
++ * As this may not be anonymous memory (e.g. shmem)
++ * but exist on a real mapping, we have to lock
++ * the page in order to dirty it -- holding
++ * the page reference is not sufficient to
++ * prevent the inode from being truncated.
++ * Play safe and take the lock.
++ */
++ set_page_dirty_lock(page);
+
+ mark_page_accessed(page);
+ put_page(page);
diff --git a/patches.drm/drm-nouveau-fix-memory-leak-in-nouveau_conn_reset.patch b/patches.drm/drm-nouveau-fix-memory-leak-in-nouveau_conn_reset.patch
new file mode 100644
index 0000000000..d70b00faf8
--- /dev/null
+++ b/patches.drm/drm-nouveau-fix-memory-leak-in-nouveau_conn_reset.patch
@@ -0,0 +1,63 @@
+From 09b90e2fe35faeace2488234e2a7728f2ea8ba26 Mon Sep 17 00:00:00 2001
+From: Yongxin Liu <yongxin.liu@windriver.com>
+Date: Mon, 1 Jul 2019 09:46:22 +0800
+Subject: [PATCH] drm/nouveau: fix memory leak in nouveau_conn_reset()
+Git-commit: 09b90e2fe35faeace2488234e2a7728f2ea8ba26
+Patch-mainline: v5.3-rc1
+References: bsc#1051510
+
+In nouveau_conn_reset(), if connector->state is true,
+__drm_atomic_helper_connector_destroy_state() will be called,
+but the memory pointed by asyc isn't freed. Memory leak happens
+in the following function __drm_atomic_helper_connector_reset(),
+where newly allocated asyc->state will be assigned to connector->state.
+
+So using nouveau_conn_atomic_destroy_state() instead of
+__drm_atomic_helper_connector_destroy_state to free the "old" asyc.
+
+Here the is the log showing memory leak.
+
+unreferenced object 0xffff8c5480483c80 (size 192):
+ comm "kworker/0:2", pid 188, jiffies 4294695279 (age 53.179s)
+ hex dump (first 32 bytes):
+ 00 f0 ba 7b 54 8c ff ff 00 00 00 00 00 00 00 00 ...{T...........
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace:
+ [<000000005005c0d0>] kmem_cache_alloc_trace+0x195/0x2c0
+ [<00000000a122baed>] nouveau_conn_reset+0x25/0xc0 [nouveau]
+ [<000000004fd189a2>] nouveau_connector_create+0x3a7/0x610 [nouveau]
+ [<00000000c73343a8>] nv50_display_create+0x343/0x980 [nouveau]
+ [<000000002e2b03c3>] nouveau_display_create+0x51f/0x660 [nouveau]
+ [<00000000c924699b>] nouveau_drm_device_init+0x182/0x7f0 [nouveau]
+ [<00000000cc029436>] nouveau_drm_probe+0x20c/0x2c0 [nouveau]
+ [<000000007e961c3e>] local_pci_probe+0x47/0xa0
+ [<00000000da14d569>] work_for_cpu_fn+0x1a/0x30
+ [<0000000028da4805>] process_one_work+0x27c/0x660
+ [<000000001d415b04>] worker_thread+0x22b/0x3f0
+ [<0000000003b69f1f>] kthread+0x12f/0x150
+ [<00000000c94c29b7>] ret_from_fork+0x3a/0x50
+
+Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/gpu/drm/nouveau/nouveau_connector.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
+index caa8c7595889..8f15281faa79 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
++++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
+@@ -252,7 +252,7 @@ nouveau_conn_reset(struct drm_connector *connector)
+ return;
+
+ if (connector->state)
+- __drm_atomic_helper_connector_destroy_state(connector->state);
++ nouveau_conn_atomic_destroy_state(connector, connector->state);
+ __drm_atomic_helper_connector_reset(connector, &asyc->state);
+ asyc->dither.mode = DITHERING_MODE_AUTO;
+ asyc->dither.depth = DITHERING_DEPTH_AUTO;
+--
+2.16.4
+
diff --git a/patches.fixes/s390-qeth-avoid-control-io-completion-stalls b/patches.fixes/s390-qeth-avoid-control-io-completion-stalls
new file mode 100644
index 0000000000..e42be391b2
--- /dev/null
+++ b/patches.fixes/s390-qeth-avoid-control-io-completion-stalls
@@ -0,0 +1,120 @@
+From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+Date: Thu, 19 Apr 2018 12:52:07 +0200
+Subject: s390/qeth: avoid control IO completion stalls
+Git-commit: 901e3f49facbd31b2b3d1786637b4a35e1022e9b
+Patch-mainline: v4.17-rc3
+References: bsc#1142109 LTC#179339
+
+For control IO, qeth currently tracks the index of the buffer that it
+expects to complete the next IO on each qeth_channel. If the channel
+presents an IRQ while this buffer has not yet completed, no completion
+processing for _any_ completed buffer takes place.
+So if the 'next buffer' is skipped for any sort of reason* (eg. when it
+is released due to error conditions, before the IO is started), the
+buffer obviously won't switch to PROCESSED until it is eventually
+allocated for a _different_ IO and completes.
+Until this happens, all completion processing on that channel stalls
+and pending requests possibly time out.
+
+As a fix, remove the whole 'next buffer' logic and simply process any
+IO buffer right when it completes. A channel will never have more than
+one IO pending, so there's no risk of processing out-of-sequence.
+
+*Note: currently just one location in the code really handles this problem,
+ by advancing the 'next' index manually.
+
+Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Petr Tesarik <ptesarik@suse.com>
+---
+ drivers/s390/net/qeth_core.h | 2 --
+ drivers/s390/net/qeth_core_main.c | 22 +++++-----------------
+ 2 files changed, 5 insertions(+), 19 deletions(-)
+
+--- a/drivers/s390/net/qeth_core.h
++++ b/drivers/s390/net/qeth_core.h
+@@ -568,7 +568,6 @@ enum qeth_ip_types {
+ enum qeth_cmd_buffer_state {
+ BUF_STATE_FREE,
+ BUF_STATE_LOCKED,
+- BUF_STATE_PROCESSED,
+ };
+
+ enum qeth_cq {
+@@ -612,7 +611,6 @@ struct qeth_channel {
+ struct qeth_cmd_buffer iob[QETH_CMD_BUFFER_NO];
+ atomic_t irq_pending;
+ int io_buf_no;
+- int buf_no;
+ };
+
+ /**
+--- a/drivers/s390/net/qeth_core_main.c
++++ b/drivers/s390/net/qeth_core_main.c
+@@ -819,7 +819,6 @@ void qeth_clear_cmd_buffers(struct qeth_
+
+ for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++)
+ qeth_release_buffer(channel, &channel->iob[cnt]);
+- channel->buf_no = 0;
+ channel->io_buf_no = 0;
+ }
+ EXPORT_SYMBOL_GPL(qeth_clear_cmd_buffers);
+@@ -925,7 +924,6 @@ static int qeth_setup_channel(struct qet
+ kfree(channel->iob[cnt].data);
+ return -ENOMEM;
+ }
+- channel->buf_no = 0;
+ channel->io_buf_no = 0;
+ atomic_set(&channel->irq_pending, 0);
+ spin_lock_init(&channel->iob_lock);
+@@ -1101,11 +1099,9 @@ static void qeth_irq(struct ccw_device *
+ {
+ int rc;
+ int cstat, dstat;
+- struct qeth_cmd_buffer *buffer;
+ struct qeth_channel *channel;
+ struct qeth_card *card;
+ struct qeth_cmd_buffer *iob;
+- __u8 index;
+
+ if (__qeth_check_irb_error(cdev, intparm, irb))
+ return;
+@@ -1183,25 +1179,18 @@ static void qeth_irq(struct ccw_device *
+ channel->state = CH_STATE_RCD_DONE;
+ goto out;
+ }
+- if (intparm) {
+- buffer = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
+- buffer->state = BUF_STATE_PROCESSED;
+- }
+ if (channel == &card->data)
+ return;
+ if (channel == &card->read &&
+ channel->state == CH_STATE_UP)
+ __qeth_issue_next_read(card);
+
+- iob = channel->iob;
+- index = channel->buf_no;
+- while (iob[index].state == BUF_STATE_PROCESSED) {
+- if (iob[index].callback != NULL)
+- iob[index].callback(channel, iob + index);
+-
+- index = (index + 1) % QETH_CMD_BUFFER_NO;
++ if (intparm) {
++ iob = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
++ if (iob->callback)
++ iob->callback(iob->channel, iob);
+ }
+- channel->buf_no = index;
++
+ out:
+ wake_up(&card->wait_q);
+ return;
+@@ -2166,7 +2155,6 @@ time_err:
+ error:
+ atomic_set(&card->write.irq_pending, 0);
+ qeth_release_buffer(iob->channel, iob);
+- card->write.buf_no = (card->write.buf_no + 1) % QETH_CMD_BUFFER_NO;
+ rc = reply->rc;
+ qeth_put_reply(reply);
+ return rc;
diff --git a/patches.fixes/s390-qeth-cancel-cmd-on-early-error b/patches.fixes/s390-qeth-cancel-cmd-on-early-error
new file mode 100644
index 0000000000..eebc1a1d35
--- /dev/null
+++ b/patches.fixes/s390-qeth-cancel-cmd-on-early-error
@@ -0,0 +1,135 @@
+From: Julian Wiedmann <jwi@linux.ibm.com>
+Date: Tue, 12 Feb 2019 18:33:22 +0100
+Subject: s390/qeth: cancel cmd on early error
+Git-commit: 54daaca7024d5419dad64db8a3e65f6b38f24b7f
+Patch-mainline: v5.1-rc1
+References: bsc#1142109 LTC#179339
+
+When sending cmds via qeth_send_control_data(), qeth puts the request
+on the IO channel and then blocks on the reply object until the response
+has been received.
+
+If the IO completes with error, there will never be a response and we
+block until the reply-wait hits its timeout. For this case, connect the
+request buffer to its reply object, so that we can immediately cancel
+the wait.
+
+Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[ ptesarik: Use __qeth_check_irb_error instead of qeth_check_irb_error.
+ Renamed by 8d908eb045bb1ad8a842910360938a204a203617. ]
+Signed-off-by: Petr Tesarik <ptesarik@suse.com>
+---
+ drivers/s390/net/qeth_core.h | 1 +
+ drivers/s390/net/qeth_core_main.c | 34 +++++++++++++++++++++++++++-------
+ 2 files changed, 28 insertions(+), 7 deletions(-)
+
+--- a/drivers/s390/net/qeth_core.h
++++ b/drivers/s390/net/qeth_core.h
+@@ -602,6 +602,7 @@ struct qeth_channel;
+ struct qeth_cmd_buffer {
+ enum qeth_cmd_buffer_state state;
+ struct qeth_channel *channel;
++ struct qeth_reply *reply;
+ unsigned char *data;
+ int rc;
+ void (*callback) (struct qeth_channel *, struct qeth_cmd_buffer *);
+--- a/drivers/s390/net/qeth_core_main.c
++++ b/drivers/s390/net/qeth_core_main.c
+@@ -810,12 +810,27 @@ void qeth_release_buffer(struct qeth_cha
+ memset(iob->data, 0, QETH_BUFSIZE);
+ iob->state = BUF_STATE_FREE;
+ iob->callback = qeth_send_control_data_cb;
++ if (iob->reply) {
++ qeth_put_reply(iob->reply);
++ iob->reply = NULL;
++ }
+ iob->rc = 0;
+ spin_unlock_irqrestore(&channel->iob_lock, flags);
+ wake_up(&channel->wait_q);
+ }
+ EXPORT_SYMBOL_GPL(qeth_release_buffer);
+
++static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc)
++{
++ struct qeth_reply *reply = iob->reply;
++
++ if (reply) {
++ reply->rc = rc;
++ qeth_notify_reply(reply);
++ }
++ qeth_release_buffer(iob->channel, iob);
++}
++
+ static struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel)
+ {
+ struct qeth_cmd_buffer *buffer = NULL;
+@@ -1076,7 +1091,7 @@ static int qeth_get_problem(struct ccw_d
+ return 0;
+ }
+
+-static long __qeth_check_irb_error(struct ccw_device *cdev,
++static int __qeth_check_irb_error(struct ccw_device *cdev,
+ unsigned long intparm, struct irb *irb)
+ {
+ struct qeth_card *card;
+@@ -1092,7 +1107,7 @@ static long __qeth_check_irb_error(struc
+ CCW_DEVID(cdev));
+ QETH_CARD_TEXT(card, 2, "ckirberr");
+ QETH_CARD_TEXT_(card, 2, " rc%d", -EIO);
+- break;
++ return -EIO;
+ case -ETIMEDOUT:
+ dev_warn(&cdev->dev, "A hardware operation timed out"
+ " on the device\n");
+@@ -1104,14 +1119,14 @@ static long __qeth_check_irb_error(struc
+ wake_up(&card->wait_q);
+ }
+ }
+- break;
++ return -ETIMEDOUT;
+ default:
+ QETH_DBF_MESSAGE(2, "unknown error %ld on channel %x\n",
+ PTR_ERR(irb), CCW_DEVID(cdev));
+ QETH_CARD_TEXT(card, 2, "ckirberr");
+ QETH_CARD_TEXT(card, 2, " rc???");
++ return PTR_ERR(irb);
+ }
+- return PTR_ERR(irb);
+ }
+
+ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
+@@ -1143,10 +1158,11 @@ static void qeth_irq(struct ccw_device *
+ if (qeth_intparm_is_iob(intparm))
+ iob = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
+
+- if (__qeth_check_irb_error(cdev, intparm, irb)) {
++ rc = __qeth_check_irb_error(cdev, intparm, irb);
++ if (rc) {
+ /* IO was terminated, free its resources. */
+ if (iob)
+- qeth_release_buffer(iob->channel, iob);
++ qeth_cancel_cmd(iob, rc);
+ atomic_set(&channel->irq_pending, 0);
+ wake_up(&card->wait_q);
+ return;
+@@ -1202,7 +1218,7 @@ static void qeth_irq(struct ccw_device *
+ if (rc) {
+ card->read_or_write_problem = 1;
+ if (iob)
+- qeth_release_buffer(iob->channel, iob);
++ qeth_cancel_cmd(iob, rc);
+ qeth_clear_ipacmd_list(card);
+ qeth_schedule_recovery(card);
+ goto out;
+@@ -2119,6 +2135,10 @@ int qeth_send_control_data(struct qeth_c
+ reply->callback = reply_cb;
+ reply->param = reply_param;
+
++ /* pairs with qeth_release_buffer(): */
++ qeth_get_reply(reply);
++ iob->reply = reply;
++
+ while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ;
+
+ if (IS_IPA(iob->data)) {
diff --git a/patches.fixes/s390-qeth-fix-request-side-race-during-cmd-io-timeout b/patches.fixes/s390-qeth-fix-request-side-race-during-cmd-io-timeout
new file mode 100644
index 0000000000..5f6850e412
--- /dev/null
+++ b/patches.fixes/s390-qeth-fix-request-side-race-during-cmd-io-timeout
@@ -0,0 +1,206 @@
+From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+Date: Thu, 19 Apr 2018 12:52:10 +0200
+Subject: s390/qeth: fix request-side race during cmd IO timeout
+Git-commit: db71bbbd11a4d314f0fa3fbf3369b71cf33ce33c
+Patch-mainline: v4.17-rc3
+References: bsc#1142109 LTC#179339
+
+Submitting a cmd IO request (usually on the WRITE device, but for IDX
+also on the READ device) is currently done with ccw_device_start()
+and a manual timeout in the caller.
+On timeout, the caller cleans up the related resources (eg. IO buffer).
+But 1) the IO might still be active and utilize those resources, and
+ 2) when the IO completes, qeth_irq() will attempt to clean up the
+ same resources again.
+
+Instead of introducing additional resource locking, switch to
+ccw_device_start_timeout() to ensure IO termination after timeout, and
+let the IRQ handler alone deal with cleaning up after a request.
+
+This also removes a stray write->irq_pending reset from
+clear_ipacmd_list(). The routine doesn't terminate any pending IO on
+the WRITE device, so this should be handled properly via IO timeout
+in the IRQ handler.
+
+Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Petr Tesarik <ptesarik@suse.com>
+---
+ drivers/s390/net/qeth_core_main.c | 51 +++++++++++++++++++-------------------
+ drivers/s390/net/qeth_core_mpc.h | 12 ++++++++
+ drivers/s390/net/qeth_l2_main.c | 4 +-
+ 3 files changed, 40 insertions(+), 27 deletions(-)
+
+--- a/drivers/s390/net/qeth_core_main.c
++++ b/drivers/s390/net/qeth_core_main.c
+@@ -707,7 +707,6 @@ void qeth_clear_ipacmd_list(struct qeth_
+ qeth_put_reply(reply);
+ }
+ spin_unlock_irqrestore(&card->lock, flags);
+- atomic_set(&card->write.irq_pending, 0);
+ }
+ EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list);
+
+@@ -1099,14 +1098,9 @@ static void qeth_irq(struct ccw_device *
+ {
+ int rc;
+ int cstat, dstat;
++ struct qeth_cmd_buffer *iob = NULL;
+ struct qeth_channel *channel;
+ struct qeth_card *card;
+- struct qeth_cmd_buffer *iob;
+-
+- if (__qeth_check_irb_error(cdev, intparm, irb))
+- return;
+- cstat = irb->scsw.cmd.cstat;
+- dstat = irb->scsw.cmd.dstat;
+
+ card = CARD_FROM_CDEV(cdev);
+ if (!card)
+@@ -1124,6 +1118,19 @@ static void qeth_irq(struct ccw_device *
+ channel = &card->data;
+ QETH_CARD_TEXT(card, 5, "data");
+ }
++
++ if (qeth_intparm_is_iob(intparm))
++ iob = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
++
++ if (__qeth_check_irb_error(cdev, intparm, irb)) {
++ /* IO was terminated, free its resources. */
++ if (iob)
++ qeth_release_buffer(iob->channel, iob);
++ atomic_set(&channel->irq_pending, 0);
++ wake_up(&card->wait_q);
++ return;
++ }
++
+ atomic_set(&channel->irq_pending, 0);
+
+ if (irb->scsw.cmd.fctl & (SCSW_FCTL_CLEAR_FUNC))
+@@ -1147,6 +1154,10 @@ static void qeth_irq(struct ccw_device *
+ /* we don't have to handle this further */
+ intparm = 0;
+ }
++
++ cstat = irb->scsw.cmd.cstat;
++ dstat = irb->scsw.cmd.dstat;
++
+ if ((dstat & DEV_STAT_UNIT_EXCEP) ||
+ (dstat & DEV_STAT_UNIT_CHECK) ||
+ (cstat)) {
+@@ -1185,11 +1196,8 @@ static void qeth_irq(struct ccw_device *
+ channel->state == CH_STATE_UP)
+ __qeth_issue_next_read(card);
+
+- if (intparm) {
+- iob = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
+- if (iob->callback)
+- iob->callback(iob->channel, iob);
+- }
++ if (iob && iob->callback)
++ iob->callback(iob->channel, iob);
+
+ out:
+ wake_up(&card->wait_q);
+@@ -1812,8 +1820,8 @@ static int qeth_idx_activate_get_answer(
+ atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
+ QETH_DBF_TEXT(SETUP, 6, "noirqpnd");
+ spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
+- rc = ccw_device_start(channel->ccwdev,
+- &channel->ccw, (addr_t) iob, 0, 0);
++ rc = ccw_device_start_timeout(channel->ccwdev, &channel->ccw,
++ (addr_t) iob, 0, 0, QETH_TIMEOUT);
+ spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
+
+ if (rc) {
+@@ -1830,7 +1838,6 @@ static int qeth_idx_activate_get_answer(
+ if (channel->state != CH_STATE_UP) {
+ rc = -ETIME;
+ QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
+- qeth_clear_cmd_buffers(channel);
+ } else
+ rc = 0;
+ return rc;
+@@ -1884,8 +1891,8 @@ static int qeth_idx_activate_channel(str
+ atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
+ QETH_DBF_TEXT(SETUP, 6, "noirqpnd");
+ spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
+- rc = ccw_device_start(channel->ccwdev,
+- &channel->ccw, (addr_t) iob, 0, 0);
++ rc = ccw_device_start_timeout(channel->ccwdev, &channel->ccw,
++ (addr_t) iob, 0, 0, QETH_TIMEOUT);
+ spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
+
+ if (rc) {
+@@ -1906,7 +1913,6 @@ static int qeth_idx_activate_channel(str
+ QETH_DBF_MESSAGE(2, "%s IDX activate timed out\n",
+ dev_name(&channel->ccwdev->dev));
+ QETH_DBF_TEXT_(SETUP, 2, "2err%d", -ETIME);
+- qeth_clear_cmd_buffers(channel);
+ return -ETIME;
+ }
+ return qeth_idx_activate_get_answer(channel, idx_reply_cb);
+@@ -2107,8 +2113,8 @@ int qeth_send_control_data(struct qeth_c
+
+ QETH_CARD_TEXT(card, 6, "noirqpnd");
+ spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
+- rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
+- (addr_t) iob, 0, 0);
++ rc = ccw_device_start_timeout(CARD_WDEV(card), &card->write.ccw,
++ (addr_t) iob, 0, 0, event_timeout);
+ spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
+ if (rc) {
+ QETH_DBF_MESSAGE(2, "%s qeth_send_control_data: "
+@@ -2140,8 +2146,6 @@ int qeth_send_control_data(struct qeth_c
+ }
+ }
+
+- if (reply->rc == -EIO)
+- goto error;
+ rc = reply->rc;
+ qeth_put_reply(reply);
+ return rc;
+@@ -2152,9 +2156,6 @@ time_err:
+ list_del_init(&reply->list);
+ spin_unlock_irqrestore(&reply->card->lock, flags);
+ atomic_inc(&reply->received);
+-error:
+- atomic_set(&card->write.irq_pending, 0);
+- qeth_release_buffer(iob->channel, iob);
+ rc = reply->rc;
+ qeth_put_reply(reply);
+ return rc;
+--- a/drivers/s390/net/qeth_core_mpc.h
++++ b/drivers/s390/net/qeth_core_mpc.h
+@@ -34,6 +34,18 @@ extern unsigned char IPA_PDU_HEADER[];
+ #define QETH_HALT_CHANNEL_PARM -11
+ #define QETH_RCD_PARM -12
+
++static inline bool qeth_intparm_is_iob(unsigned long intparm)
++{
++ switch (intparm) {
++ case QETH_CLEAR_CHANNEL_PARM:
++ case QETH_HALT_CHANNEL_PARM:
++ case QETH_RCD_PARM:
++ case 0:
++ return false;
++ }
++ return true;
++}
++
+ /*****************************************************************************/
+ /* IP Assist related definitions */
+ /*****************************************************************************/
+--- a/drivers/s390/net/qeth_l2_main.c
++++ b/drivers/s390/net/qeth_l2_main.c
+@@ -1391,8 +1391,8 @@ static int qeth_osn_send_control_data(st
+ qeth_prepare_control_data(card, len, iob);
+ QETH_CARD_TEXT(card, 6, "osnoirqp");
+ spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
+- rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
+- (addr_t) iob, 0, 0);
++ rc = ccw_device_start_timeout(CARD_WDEV(card), &card->write.ccw,
++ (addr_t) iob, 0, 0, QETH_IPA_TIMEOUT);
+ spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
+ if (rc) {
+ QETH_DBF_MESSAGE(2, "qeth_osn_send_control_data: "
diff --git a/patches.fixes/s390-qeth-release-cmd-buffer-in-error-paths b/patches.fixes/s390-qeth-release-cmd-buffer-in-error-paths
new file mode 100644
index 0000000000..e4a8b98961
--- /dev/null
+++ b/patches.fixes/s390-qeth-release-cmd-buffer-in-error-paths
@@ -0,0 +1,62 @@
+From: Julian Wiedmann <jwi@linux.ibm.com>
+Date: Mon, 4 Feb 2019 17:40:06 +0100
+Subject: s390/qeth: release cmd buffer in error paths
+Git-commit: 5065b2dd3e5f9247a6c9d67974bc0472bf561b9d
+Patch-mainline: v5.0-rc6
+References: bsc#1142109 LTC#179339
+
+Whenever we fail before/while starting an IO, make sure to release the
+IO buffer. Usually qeth_irq() would do this for us, but if the IO
+doesn't even start we obviously won't get an interrupt for it either.
+
+Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[ ptesarik: Use iob->channel where channel is not declared. ]
+Signed-off-by: Petr Tesarik <ptesarik@suse.com>
+---
+ drivers/s390/net/qeth_core_main.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/s390/net/qeth_core_main.c
++++ b/drivers/s390/net/qeth_core_main.c
+@@ -559,6 +559,7 @@ static int __qeth_issue_next_read(struct
+ QETH_DBF_MESSAGE(2, "error %i on device %x when starting next read ccw!\n",
+ rc, CARD_DEVID(card));
+ atomic_set(&card->read.irq_pending, 0);
++ qeth_release_buffer(iob->channel, iob);
+ card->read_or_write_problem = 1;
+ qeth_schedule_recovery(card);
+ wake_up(&card->wait_q);
+@@ -1187,6 +1188,8 @@ static void qeth_irq(struct ccw_device *
+ rc = qeth_get_problem(cdev, irb);
+ if (rc) {
+ card->read_or_write_problem = 1;
++ if (iob)
++ qeth_release_buffer(iob->channel, iob);
+ qeth_clear_ipacmd_list(card);
+ qeth_schedule_recovery(card);
+ goto out;
+@@ -1835,6 +1838,7 @@ static int qeth_idx_activate_get_answer(
+ QETH_DBF_MESSAGE(2, "Error2 in activating channel rc=%d\n", rc);
+ QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
+ atomic_set(&channel->irq_pending, 0);
++ qeth_release_buffer(channel, iob);
+ wake_up(&card->wait_q);
+ return rc;
+ }
+@@ -1907,6 +1911,7 @@ static int qeth_idx_activate_channel(str
+ rc);
+ QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
+ atomic_set(&channel->irq_pending, 0);
++ qeth_release_buffer(channel, iob);
+ wake_up(&card->wait_q);
+ return rc;
+ }
+@@ -2089,6 +2094,7 @@ int qeth_send_control_data(struct qeth_c
+ }
+ reply = qeth_alloc_reply(card);
+ if (!reply) {
++ qeth_release_buffer(iob->channel, iob);
+ return -ENOMEM;
+ }
+ reply->callback = reply_cb;
diff --git a/patches.fixes/s390-qeth-simplify-reply-object-handling b/patches.fixes/s390-qeth-simplify-reply-object-handling
new file mode 100644
index 0000000000..0865c1617f
--- /dev/null
+++ b/patches.fixes/s390-qeth-simplify-reply-object-handling
@@ -0,0 +1,231 @@
+From: Julian Wiedmann <jwi@linux.ibm.com>
+Date: Tue, 12 Feb 2019 18:33:21 +0100
+Subject: s390/qeth: simplify reply object handling
+Git-commit: 0951c6babf49d2f2429cbfbea5cf792d427ecc6a
+Patch-mainline: v5.1-rc1
+References: bsc#1142109 LTC#179339
+
+Current code enqueues & dequeues a reply object from the waiter list
+in various places. In particular, the dequeue & enqueue in
+qeth_send_control_data_cb() looks fragile - this can cause
+qeth_clear_ipacmd_list() to skip the active object.
+Add some helpers, and boil the logic down by giving
+qeth_send_control_data() the sole responsibility to add and remove
+objects.
+
+qeth_send_control_data_cb() and qeth_clear_ipacmd_list() will now only
+notify the reply object to interrupt its wait cycle. This can cause
+a slight delay in the removal, but that's no concern.
+
+Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[ ptesarik: Replace spin_unlock_irqrestore() instead of spin_unlock_irq()
+ as an alternative to backporting ed47155bdcf38ff5a0f419b7a833dcbe49cb8abc ]
+Signed-off-by: Petr Tesarik <ptesarik@suse.com>
+---
+ drivers/s390/net/qeth_core_main.c | 118 +++++++++++++++++++-------------------
+ 1 file changed, 61 insertions(+), 57 deletions(-)
+
+--- a/drivers/s390/net/qeth_core_main.c
++++ b/drivers/s390/net/qeth_core_main.c
+@@ -585,6 +585,7 @@ static struct qeth_reply *qeth_alloc_rep
+ if (reply) {
+ atomic_set(&reply->refcnt, 1);
+ atomic_set(&reply->received, 0);
++ init_waitqueue_head(&reply->wait_q);
+ reply->card = card;
+ }
+ return reply;
+@@ -603,6 +604,26 @@ static void qeth_put_reply(struct qeth_r
+ kfree(reply);
+ }
+
++static void qeth_enqueue_reply(struct qeth_card *card, struct qeth_reply *reply)
++{
++ spin_lock_irq(&card->lock);
++ list_add_tail(&reply->list, &card->cmd_waiter_list);
++ spin_unlock_irq(&card->lock);
++}
++
++static void qeth_dequeue_reply(struct qeth_card *card, struct qeth_reply *reply)
++{
++ spin_lock_irq(&card->lock);
++ list_del(&reply->list);
++ spin_unlock_irq(&card->lock);
++}
++
++static void qeth_notify_reply(struct qeth_reply *reply)
++{
++ atomic_inc(&reply->received);
++ wake_up(&reply->wait_q);
++}
++
+ static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc,
+ struct qeth_card *card)
+ {
+@@ -699,19 +720,15 @@ static struct qeth_ipa_cmd *qeth_check_i
+
+ void qeth_clear_ipacmd_list(struct qeth_card *card)
+ {
+- struct qeth_reply *reply, *r;
++ struct qeth_reply *reply;
+ unsigned long flags;
+
+ QETH_CARD_TEXT(card, 4, "clipalst");
+
+ spin_lock_irqsave(&card->lock, flags);
+- list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
+- qeth_get_reply(reply);
++ list_for_each_entry(reply, &card->cmd_waiter_list, list) {
+ reply->rc = -EIO;
+- atomic_inc(&reply->received);
+- list_del_init(&reply->list);
+- wake_up(&reply->wait_q);
+- qeth_put_reply(reply);
++ qeth_notify_reply(reply);
+ }
+ spin_unlock_irqrestore(&card->lock, flags);
+ }
+@@ -833,10 +850,11 @@ static void qeth_send_control_data_cb(st
+ struct qeth_cmd_buffer *iob)
+ {
+ struct qeth_card *card;
+- struct qeth_reply *reply, *r;
++ struct qeth_reply *reply = NULL;
++ struct qeth_reply *r;
+ struct qeth_ipa_cmd *cmd;
+ unsigned long flags;
+- int keep_reply;
++ int keep_reply = 0;
+ int rc = 0;
+
+ card = CARD_FROM_CDEV(channel->ccwdev);
+@@ -865,44 +883,40 @@ static void qeth_send_control_data_cb(st
+ goto out;
+ }
+
++ /* match against pending cmd requests */
+ spin_lock_irqsave(&card->lock, flags);
+- list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
+- if ((reply->seqno == QETH_IDX_COMMAND_SEQNO) ||
+- ((cmd) && (reply->seqno == cmd->hdr.seqno))) {
++ list_for_each_entry(r, &card->cmd_waiter_list, list) {
++ if ((r->seqno == QETH_IDX_COMMAND_SEQNO) ||
++ (cmd && (r->seqno == cmd->hdr.seqno))) {
++ reply = r;
++ /* take the object outside the lock */
+ qeth_get_reply(reply);
+- list_del_init(&reply->list);
+- spin_unlock_irqrestore(&card->lock, flags);
+- keep_reply = 0;
+- if (reply->callback != NULL) {
+- if (cmd) {
+- reply->offset = (__u16)((char *)cmd -
+- (char *)iob->data);
+- keep_reply = reply->callback(card,
+- reply,
+- (unsigned long)cmd);
+- } else
+- keep_reply = reply->callback(card,
+- reply,
+- (unsigned long)iob);
+- }
+- if (cmd)
+- reply->rc = (u16) cmd->hdr.return_code;
+- else if (iob->rc)
+- reply->rc = iob->rc;
+- if (keep_reply) {
+- spin_lock_irqsave(&card->lock, flags);
+- list_add_tail(&reply->list,
+- &card->cmd_waiter_list);
+- spin_unlock_irqrestore(&card->lock, flags);
+- } else {
+- atomic_inc(&reply->received);
+- wake_up(&reply->wait_q);
+- }
+- qeth_put_reply(reply);
+- goto out;
++ break;
+ }
+ }
+ spin_unlock_irqrestore(&card->lock, flags);
++
++ if (!reply)
++ goto out;
++
++ if (reply->callback) {
++ if (cmd) {
++ reply->offset = (u16)((char *)cmd - (char *)iob->data);
++ keep_reply = reply->callback(card, reply,
++ (unsigned long)cmd);
++ } else
++ keep_reply = reply->callback(card, reply,
++ (unsigned long)iob);
++ }
++ if (cmd)
++ reply->rc = (u16) cmd->hdr.return_code;
++ else if (iob->rc)
++ reply->rc = iob->rc;
++
++ if (!keep_reply)
++ qeth_notify_reply(reply);
++ qeth_put_reply(reply);
++
+ out:
+ memcpy(&card->seqno.pdu_hdr_ack,
+ QETH_PDU_HEADER_SEQ_NO(iob->data),
+@@ -2105,8 +2119,6 @@ int qeth_send_control_data(struct qeth_c
+ reply->callback = reply_cb;
+ reply->param = reply_param;
+
+- init_waitqueue_head(&reply->wait_q);
+-
+ while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ;
+
+ if (IS_IPA(iob->data)) {
+@@ -2120,9 +2132,7 @@ int qeth_send_control_data(struct qeth_c
+ }
+ qeth_prepare_control_data(card, len, iob);
+
+- spin_lock_irqsave(&card->lock, flags);
+- list_add_tail(&reply->list, &card->cmd_waiter_list);
+- spin_unlock_irqrestore(&card->lock, flags);
++ qeth_enqueue_reply(card, reply);
+ timeout = jiffies + event_timeout;
+
+ QETH_CARD_TEXT(card, 6, "noirqpnd");
+@@ -2134,10 +2144,8 @@ int qeth_send_control_data(struct qeth_c
+ QETH_DBF_MESSAGE(2, "qeth_send_control_data on device %x: ccw_device_start rc = %i\n",
+ CARD_DEVID(card), rc);
+ QETH_CARD_TEXT_(card, 2, " err%d", rc);
+- spin_lock_irqsave(&card->lock, flags);
+- list_del_init(&reply->list);
++ qeth_dequeue_reply(card, reply);
+ qeth_put_reply(reply);
+- spin_unlock_irqrestore(&card->lock, flags);
+ qeth_release_buffer(iob->channel, iob);
+ atomic_set(&card->write.irq_pending, 0);
+ wake_up(&card->wait_q);
+@@ -2159,19 +2167,15 @@ int qeth_send_control_data(struct qeth_c
+ }
+ }
+
++ qeth_dequeue_reply(card, reply);
+ rc = reply->rc;
+ qeth_put_reply(reply);
+ return rc;
+
+ time_err:
+- reply->rc = -ETIME;
+- spin_lock_irqsave(&reply->card->lock, flags);
+- list_del_init(&reply->list);
+- spin_unlock_irqrestore(&reply->card->lock, flags);
+- atomic_inc(&reply->received);
+- rc = reply->rc;
++ qeth_dequeue_reply(card, reply);
+ qeth_put_reply(reply);
+- return rc;
++ return -ETIME;
+ }
+ EXPORT_SYMBOL_GPL(qeth_send_control_data);
+
diff --git a/patches.kabi/0001-kABI-Preserve-kABI-for-dma_max_mapping_size.patch b/patches.kabi/0001-kABI-Preserve-kABI-for-dma_max_mapping_size.patch
index e0b839523b..f12d7c4805 100644
--- a/patches.kabi/0001-kABI-Preserve-kABI-for-dma_max_mapping_size.patch
+++ b/patches.kabi/0001-kABI-Preserve-kABI-for-dma_max_mapping_size.patch
@@ -11,11 +11,9 @@ Signed-off-by: Joerg Roedel <jroedel@suse.de>
include/linux/dma-mapping.h | 7 +++----
2 files changed, 3 insertions(+), 5 deletions(-)
-diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
-index 0b0e23f2ddcc..677077510e30 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
-@@ -60,7 +60,6 @@ static const struct dma_map_ops swiotlb_dma_ops = {
+@@ -60,7 +60,6 @@ static const struct dma_map_ops swiotlb_
.map_page = swiotlb_map_page,
.unmap_page = swiotlb_unmap_page,
.dma_supported = NULL,
@@ -23,8 +21,6 @@ index 0b0e23f2ddcc..677077510e30 100644
};
/*
-diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
-index 4e1cd7c6345c..33531be3f5f8 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -11,6 +11,7 @@
@@ -43,7 +39,7 @@ index 4e1cd7c6345c..33531be3f5f8 100644
#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
u64 (*get_required_mask)(struct device *dev);
#endif
-@@ -604,11 +604,10 @@ static inline u64 dma_get_mask(struct device *dev)
+@@ -604,11 +604,10 @@ static inline u64 dma_get_mask(struct de
static inline size_t dma_max_mapping_size(struct device *dev)
{
@@ -57,6 +53,13 @@ index 4e1cd7c6345c..33531be3f5f8 100644
return size;
}
---
-2.16.3
-
+--- a/arch/x86/mm/mem_encrypt.c
++++ b/arch/x86/mm/mem_encrypt.c
+@@ -424,7 +424,6 @@ static const struct dma_map_ops sev_dma_
+ .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+ .sync_sg_for_device = swiotlb_sync_sg_for_device,
+ .mapping_error = swiotlb_dma_mapping_error,
+- .max_mapping_size = swiotlb_max_mapping_size,
+ };
+
+ /* Architecture __weak replacement functions */
diff --git a/patches.kabi/kabi-x86-microcode-hotplug-state-fix.patch b/patches.kabi/kabi-x86-microcode-hotplug-state-fix.patch
index e180f9a6e5..894263fe9d 100644
--- a/patches.kabi/kabi-x86-microcode-hotplug-state-fix.patch
+++ b/patches.kabi/kabi-x86-microcode-hotplug-state-fix.patch
@@ -16,16 +16,16 @@ Signed-off-by: Borislav Petkov <bp@suse.de>
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
-@@ -853,6 +853,9 @@ int __init microcode_init(void)
+@@ -856,6 +856,9 @@ int __init microcode_init(void)
goto out_ucode_group;
register_syscore_ops(&mc_syscore_ops);
+
+#define CPUHP_AP_MICROCODE_LOADER CPUHP_AP_ARM_MVEBU_COHERENCY
+
- cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:online",
- mc_cpu_online, mc_cpu_down_prep);
-
+ cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:starting",
+ mc_cpu_starting, NULL);
+ cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/microcode:online",
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -83,8 +83,7 @@ enum cpuhp_state {
diff --git a/patches.suse/0031-bcache-use-sysfs_match_string-instead-of-__sysfs_mat.patch b/patches.suse/0031-bcache-use-sysfs_match_string-instead-of-__sysfs_mat.patch
deleted file mode 100644
index f3289af8cb..0000000000
--- a/patches.suse/0031-bcache-use-sysfs_match_string-instead-of-__sysfs_mat.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 89e0341af082dbc170019f908846f4a424efc86b Mon Sep 17 00:00:00 2001
-From: Alexandru Ardelean <alexandru.ardelean@analog.com>
-Date: Fri, 28 Jun 2019 19:59:32 +0800
-Subject: [PATCH] bcache: use sysfs_match_string() instead of
- __sysfs_match_string()
-Git-commit: 89e0341af082dbc170019f908846f4a424efc86b
-References: bsc#1140652
-Patch-mainline: v5.3-rc1
-
-The arrays (of strings) that are passed to __sysfs_match_string() are
-static, so use sysfs_match_string() which does an implicit ARRAY_SIZE()
-over these arrays.
-
-Functionally, this doesn't change anything.
-The change is more cosmetic.
-
-It only shrinks the static arrays by 1 byte each.
-
-Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
-Signed-off-by: Coly Li <colyli@suse.de>
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-
----
- drivers/md/bcache/sysfs.c | 20 ++++++++------------
- 1 file changed, 8 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
-index bfb437ffb13c..760cf8951338 100644
---- a/drivers/md/bcache/sysfs.c
-+++ b/drivers/md/bcache/sysfs.c
-@@ -21,28 +21,24 @@ static const char * const bch_cache_modes[] = {
- "writethrough",
- "writeback",
- "writearound",
-- "none",
-- NULL
-+ "none"
- };
-
- /* Default is 0 ("auto") */
- static const char * const bch_stop_on_failure_modes[] = {
- "auto",
-- "always",
-- NULL
-+ "always"
- };
-
- static const char * const cache_replacement_policies[] = {
- "lru",
- "fifo",
-- "random",
-- NULL
-+ "random"
- };
-
- static const char * const error_actions[] = {
- "unregister",
-- "panic",
-- NULL
-+ "panic"
- };
-
- write_attribute(attach);
-@@ -333,7 +329,7 @@ STORE(__cached_dev)
- bch_cached_dev_run(dc);
-
- if (attr == &sysfs_cache_mode) {
-- v = __sysfs_match_string(bch_cache_modes, -1, buf);
-+ v = sysfs_match_string(bch_cache_modes, buf);
- if (v < 0)
- return v;
-
-@@ -344,7 +340,7 @@ STORE(__cached_dev)
- }
-
- if (attr == &sysfs_stop_when_cache_set_failed) {
-- v = __sysfs_match_string(bch_stop_on_failure_modes, -1, buf);
-+ v = sysfs_match_string(bch_stop_on_failure_modes, buf);
- if (v < 0)
- return v;
-
-@@ -799,7 +795,7 @@ STORE(__bch_cache_set)
- 0, UINT_MAX);
-
- if (attr == &sysfs_errors) {
-- v = __sysfs_match_string(error_actions, -1, buf);
-+ v = sysfs_match_string(error_actions, buf);
- if (v < 0)
- return v;
-
-@@ -1063,7 +1059,7 @@ STORE(__bch_cache)
- }
-
- if (attr == &sysfs_cache_replacement_policy) {
-- v = __sysfs_match_string(cache_replacement_policies, -1, buf);
-+ v = sysfs_match_string(cache_replacement_policies, buf);
- if (v < 0)
- return v;
-
---
-2.16.4
-
diff --git a/patches.suse/0032-bcache-add-return-value-check-to-bch_cached_dev_run.patch b/patches.suse/0032-bcache-add-return-value-check-to-bch_cached_dev_run.patch
index 25f5ceacda..662c1b94ba 100644
--- a/patches.suse/0032-bcache-add-return-value-check-to-bch_cached_dev_run.patch
+++ b/patches.suse/0032-bcache-add-return-value-check-to-bch_cached_dev_run.patch
@@ -137,7 +137,7 @@ Signed-off-by: Jens Axboe <axboe@kernel.dk>
/* Flash only volumes */
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
-@@ -324,8 +324,11 @@ STORE(__cached_dev)
+@@ -328,8 +328,11 @@ STORE(__cached_dev)
bch_cache_accounting_clear(&dc->accounting);
if (attr == &sysfs_running &&
@@ -150,4 +150,4 @@ Signed-off-by: Jens Axboe <axboe@kernel.dk>
+ }
if (attr == &sysfs_cache_mode) {
- v = sysfs_match_string(bch_cache_modes, buf);
+ v = __sysfs_match_string(bch_cache_modes, -1, buf);
diff --git a/scripts/git_sort/README.md b/scripts/git_sort/README.md
index b9881372cd..09b09cf3a7 100644
--- a/scripts/git_sort/README.md
+++ b/scripts/git_sort/README.md
@@ -29,7 +29,7 @@ copy.
Packages are available in the following OBS project
https://build.opensuse.org/package/show/home:benjamin_poirier:series_sort/quilt-ks
Source is avaible from
-https://gitlab.suse.de/benjamin_poirier/quilt
+https://github.com/gobenji/quilt
The packages in home:benjamin_poirier:series_sort are signed with the key
from home:benjamin_poirier which has the following fingerprint:
diff --git a/scripts/git_sort/lib.py b/scripts/git_sort/lib.py
index 9f7da0efb6..4a4f9d3241 100644
--- a/scripts/git_sort/lib.py
+++ b/scripts/git_sort/lib.py
@@ -26,6 +26,7 @@ import re
import signal
import subprocess
import sys
+import weakref
import pygit2_wrapper as pygit2
@@ -558,3 +559,82 @@ def sequence_insert(series, rev, top):
"Please run scripts/series_sort.py.")
return (name, commit_pos - top_index,)
+
+
+# https://github.com/ActiveState/code/tree/master/recipes/Python/576696_OrderedSet_with_Weakrefs
+class Link(object):
+ __slots__ = 'prev', 'next', 'key', '__weakref__'
+
+
+class OrderedSet(collections.MutableSet):
+ 'Set the remembers the order elements were added'
+ # Big-O running times for all methods are the same as for regular sets.
+ # The internal self.__map dictionary maps keys to links in a doubly linked list.
+ # The circular doubly linked list starts and ends with a sentinel element.
+ # The sentinel element never gets deleted (this simplifies the algorithm).
+ # The prev/next links are weakref proxies (to prevent circular references).
+ # Individual links are kept alive by the hard reference in self.__map.
+ # Those hard references disappear when a key is deleted from an OrderedSet.
+
+ def __init__(self, iterable=None):
+ self.__root = root = Link() # sentinel node for doubly linked list
+ root.prev = root.next = root
+ self.__map = {} # key --> link
+ if iterable is not None:
+ self |= iterable
+
+ def __len__(self):
+ return len(self.__map)
+
+ def __contains__(self, key):
+ return key in self.__map
+
+ def add(self, key):
+ # Store new key in a new link at the end of the linked list
+ if key not in self.__map:
+ self.__map[key] = link = Link()
+ root = self.__root
+ last = root.prev
+ link.prev, link.next, link.key = last, root, key
+ last.next = root.prev = weakref.proxy(link)
+
+ def discard(self, key):
+ # Remove an existing item using self.__map to find the link which is
+ # then removed by updating the links in the predecessor and successors.
+ if key in self.__map:
+ link = self.__map.pop(key)
+ link.prev.next = link.next
+ link.next.prev = link.prev
+
+ def __iter__(self):
+ # Traverse the linked list in order.
+ root = self.__root
+ curr = root.next
+ while curr is not root:
+ yield curr.key
+ curr = curr.next
+
+ def __reversed__(self):
+ # Traverse the linked list in reverse order.
+ root = self.__root
+ curr = root.prev
+ while curr is not root:
+ yield curr.key
+ curr = curr.prev
+
+ def pop(self, last=True):
+ if not self:
+ raise KeyError('set is empty')
+ key = next(reversed(self)) if last else next(iter(self))
+ self.discard(key)
+ return key
+
+ def __repr__(self):
+ if not self:
+ return '%s()' % (self.__class__.__name__,)
+ return '%s(%r)' % (self.__class__.__name__, list(self))
+
+ def __eq__(self, other):
+ if isinstance(other, OrderedSet):
+ return len(self) == len(other) and list(self) == list(other)
+ return not self.isdisjoint(other)
diff --git a/scripts/git_sort/merge_tool.py b/scripts/git_sort/merge_tool.py
index fda4c3478f..60433fcbba 100755
--- a/scripts/git_sort/merge_tool.py
+++ b/scripts/git_sort/merge_tool.py
@@ -63,9 +63,9 @@ if __name__ == "__main__":
# (before, inside, after, set(inside),)
local, base, remote = (
- (s[0], s[1], s[2], set([series_conf.firstword(l)
- for l in s[1]
- if series_conf.filter_patches(l)]),)
+ (s[0], s[1], s[2], lib.OrderedSet([series_conf.firstword(l)
+ for l in s[1]
+ if series_conf.filter_patches(l)]),)
for s in [
series_conf.split(open(s_path))
for s_path in (local_path, base_path, remote_path,)
@@ -74,7 +74,7 @@ if __name__ == "__main__":
added = remote[3] - base[3]
removed = base[3] - remote[3]
- moved = set(lib.list_moved_patches(base[1], remote[1]))
+ moved = lib.OrderedSet(lib.list_moved_patches(base[1], remote[1]))
if added or removed:
print("%d commits added, %d commits removed from base to remote." %
diff --git a/scripts/run_oldconfig.sh b/scripts/run_oldconfig.sh
index c3c0651ab8..fb49596553 100755
--- a/scripts/run_oldconfig.sh
+++ b/scripts/run_oldconfig.sh
@@ -455,6 +455,9 @@ for config in $config_files; do
else
config_base="$(dirname "$config")/default"
fi
+ if ! [ -f "$config_base" ] && [ -n "$VARIANT" ] ; then
+ config_base="$(dirname "$config")/${VARIANT#-}"
+ fi
${scripts}/config-merge "$config_base" "$config" >$config_orig
else
cp "$config" $config_orig
diff --git a/series.conf b/series.conf
index 0747ca6b74..c960417b0e 100644
--- a/series.conf
+++ b/series.conf
@@ -2861,6 +2861,7 @@
patches.drivers/clk-renesas-r8a7745-Remove-nonexisting-scu-src-0789-
patches.drivers/clk-renesas-r8a7745-Remove-PLL-configs-for-MD19-0
patches.drivers/clk-renesas-r8a7795-Correct-pwm-gpio-and-i2c-parent-
+ patches.drivers/0001-clk-add-clk_bulk_get-accessories.patch
patches.drivers/clk-at91-fix-clk-generated-compilation
patches.drivers/0023-clk-rockchip-add-dt-binding-header-for-rk3128.patch
patches.drivers/0024-clk-rockchip-add-ids-for-rk3399-testclks-used-for-ca.patch
@@ -5499,6 +5500,7 @@
patches.drivers/gpio-brcmstb-check-return-value-of-gpiochip_irqchip_
patches.drivers/HID-hid-sensor-hub-Force-logical-minimum-to-1-for-po.patch
patches.drivers/HID-wacom-Remove-comparison-of-u8-mode-with-zero-and.patch
+ patches.drivers/pm-opp-of-use-pr_debug-instead-of-pr_err-while-adding-opp-table.patch
patches.drivers/0001-cpufreq-governor-Drop-min_sampling_rate.patch
patches.drivers/0003-cpufreq-Use-transition_delay_us-for-legacy-governors.patch
patches.drivers/0001-cpufreq-remove-setting-of-policy-cpu-in-policy-cpus-.patch
@@ -7452,6 +7454,7 @@
patches.drivers/nvme-pci-Use-PCI-bus-address-for-data-queues-in-CMB.patch
patches.fixes/xfs-always-swap-the-cow-forks-when-swapping-extents.patch
patches.fixes/xfs-handle-racy-AIO-in-xfs_reflink_end_cow.patch
+ patches.drivers/0002-clk-Export-clk_bulk_prepare.patch
patches.drivers/0003-hwmon-xgene-Fix-up-error-handling-path-mixup-in-xgen.patch
patches.drivers/0001-mmc-core-add-driver-strength-selection-when-selectin.patch
patches.drivers/mmc-sdhci-xenon-Fix-clock-resource-by-adding-an-opti
@@ -15398,6 +15401,8 @@
patches.fixes/udf-Provide-saner-default-for-invalid-uid-gid.patch
patches.drivers/dt-bindings-arm-document-soc-compatible-value-for-armadillo-800-eva.patch
patches.drivers/soc-qcom-wcnss_ctrl-Fix-increment-in-NV-upload
+ patches.drivers/0003-soc-rockchip-power-domain-use-clk_bulk-APIs.patch
+ patches.drivers/0004-soc-rockchip-power-domain-Add-a-sanity-check-on-pd-n.patch
patches.suse/0202-dm-crypt-limit-the-number-of-allocated-pages.patch
patches.suse/0203-dm-remove-unused-macro-DM_MOD_NAME_SIZE.patch
patches.suse/0204-dm-integrity-fail-early-if-required-HMAC-key-is-not-.patch
@@ -15829,7 +15834,9 @@
patches.drivers/clk-hisilicon-fix-potential-NULL-dereference-in-hisi
patches.drivers/clk-fix-false-positive-Wmaybe-uninitialized-warning
patches.drivers/clk-rockchip-Prevent-calculating-mmc-phase-if-clock-
+ patches.drivers/0001-clk-rockchip-Add-1.6GHz-PLL-rate-for-rk3399.patch
patches.drivers/clk-rockchip-Fix-wrong-parent-for-SDMMC-phase-clock-
+ patches.drivers/0002-clk-rockchip-assign-correct-id-for-pclk_ddr-and-hclk.patch
patches.drivers/clk-bcm2835-De-assert-assert-PLL-reset-signal-when-a
patches.drivers/firmware-dmi_scan-Fix-UUID-length-safety-check
patches.drivers/thermal-imx-Fix-race-condition-in-imx_thermal_probe
@@ -15953,8 +15960,10 @@
patches.drm/drm-i915-Call-i915_perf_fini-on-init_hw-error-unwind
patches.drm/drm-i915-audio-Fix-audio-detection-issue-on-GLK
patches.drivers/s390-qeth-fix-error-handling-in-adapter-command-callbacks.patch
+ patches.fixes/s390-qeth-avoid-control-io-completion-stalls
patches.arch/s390-qeth-handle-failure-on-workqueue-creation.patch
patches.arch/s390-qeth-fix-MAC-address-update-sequence.patch
+ patches.fixes/s390-qeth-fix-request-side-race-during-cmd-io-timeout
patches.suse/llc-delete-timers-synchronously-in-llc_sk_free.patch
patches.suse/net-ethernet-ti-cpsw-fix-tx-vlan-priority-mapping.patch
patches.suse/llc-fix-NULL-pointer-deref-for-SOCK_ZAPPED.patch
@@ -17409,7 +17418,9 @@
patches.drivers/0001-md-fix-two-problems-with-setting-the-re-add-device-s.patch
patches.fixes/md-fix-NULL-dereference-of-mddev-pers-in-remove_and_.patch
patches.fixes/md-raid1-add-error-handling-of-read-error-from-FailF.patch
+ patches.drivers/0005-soc-rockchip-power-domain-Use-of_clk_get_parent_coun.patch
patches.drivers/clk-qcom-Base-rcg-parent-rate-off-plan-frequency
+ patches.drivers/0003-clk-bulk-silently-error-out-on-EPROBE_DEFER.patch
patches.drivers/clk-imx7d-fix-mipi-dphy-div-parent
patches.drivers/clk-mvebu-use-correct-bit-for-98DX3236-NAND
patches.drivers/clk-at91-PLL-recalc_rate-now-using-cached-MUL-and-DI
@@ -18546,6 +18557,9 @@
patches.drivers/leds-max8997-use-mode-when-calling-max8997_led_set_m
patches.drivers/ACPI-PM-save-NVS-memory-for-ASUS-1025C-laptop
patches.drivers/dt-bindings-clock-add-rk3399-ddr3-standard-speed-bins.patch
+ patches.drivers/0007-PM-devfreq-rk3399_dmc-remove-wait-for-dcf-irq-event.patch
+ patches.drivers/0008-PM-devfreq-rk3399_dmc-do-not-print-error-when-get-su.patch
+ patches.drivers/0009-PM-devfreq-rk3399_dmc-fix-spelling-mistakes.patch
patches.arch/PM-devfreq-rk3399_dmc-Fix-duplicated-opp-table-on-re.patch
patches.drivers/0007-cpufreq-CPPC-Add-cpuinfo_cur_freq-support-for-CPPC.patch
patches.drivers/ACPI-scan-Initialize-status-to-ACPI_STA_DEFAULT.patch
@@ -19844,6 +19858,7 @@
patches.drivers/pcmcia-Implement-CLKRUN-protocol-disabling-for-Ricoh.patch
patches.fixes/cpufreq-conservative-Take-limits-changes-into-accoun.patch
patches.arch/x86-hibernate-fix-nosave_regions-setup-for-hibernation
+ patches.drivers/cpufreq-dt-try-freeing-static-opps-only-if-we-have-added-them.patch
patches.fixes/cpupower-remove-stringop-truncation-waring.patch
patches.fixes/ACPICA-AML-interpreter-add-region-addresses-in-globa.patch
patches.drivers/ACPI-LPSS-Add-alternative-ACPI-HIDs-for-Cherry-Trail.patch
@@ -21598,6 +21613,7 @@
patches.fixes/net-smc-fix-sender_free-computation
patches.fixes/net-smc-delete-rkey-first-before-switching-to-unused
patches.fixes/net-smc-correct-state-change-for-peer-closing
+ patches.fixes/s390-qeth-release-cmd-buffer-in-error-paths
patches.suse/0001-s390-qeth-fix-use-after-free-in-error-path.patch
patches.fixes/0001-s390-qeth-cancel-close_dev-work-before-removing-a-ca.patch
patches.fixes/0001-s390-qeth-conclude-all-event-processing-before-offli.patch
@@ -21799,6 +21815,8 @@
patches.fixes/net-smc-reduce-amount-of-status-updates-to-peer
patches.fixes/net-smc-check-connections-in-smc_lgr_free_work
patches.fixes/net-smc-check-port_idx-of-ib-event
+ patches.fixes/s390-qeth-simplify-reply-object-handling
+ patches.fixes/s390-qeth-cancel-cmd-on-early-error
patches.fixes/0001-cxgb4vf-Few-more-link-management-changes.patch
patches.fixes/0001-cxgb4-cxgb4vf-Add-support-for-SGE-doorbell-queue-tim.patch
patches.fixes/0001-cxgb4-Add-capability-to-get-set-SGE-Doorbell-Queue-T.patch
@@ -22593,6 +22611,9 @@
patches.drivers/cpufreq-pmac32-fix-possible-object-reference-leak.patch
patches.drivers/cpufreq-ppc_cbe-fix-possible-object-reference-leak.patch
patches.drivers/PM-core-Propagate-dev-power.wakeup_path-when-no-call.patch
+ patches.drivers/0010-PM-devfreq-rk3399_dmc-remove-unneeded-semicolon.patch
+ patches.drivers/0011-PM-devfreq-rockchip-dfi-Move-GRF-definitions-to-a-co.patch
+ patches.drivers/0012-PM-devfreq-rk3399_dmc-Pass-ODT-and-auto-power-down-p.patch
patches.fixes/ACPI-property-fix-handling-of-data_nodes-in-acpi_get.patch
patches.arch/x86-mce-fix-machine_check_poll-tests-for-error-types.patch
patches.arch/x86-mce-handle-varying-mca-bank-counts.patch
@@ -23198,6 +23219,7 @@
patches.suse/af_packet-Block-execution-of-tasks-waiting-for-trans.patch
patches.fixes/scsi-vmw_pscsi-Fix-use-after-free-in-pvscsi_queue_lc.patch
patches.fixes/efi-bgrt-Drop-BGRT-status-field-reserved-bits-check.patch
+ patches.arch/x86-microcode-fix-the-microcode-load-on-cpu-hotplug-for-real.patch
patches.fixes/Bluetooth-Fix-faulty-expression-for-minimum-encrypti.patch
patches.suse/ftrace-x86-remove-possible-deadlock-between-register_kprobe-and-ftrace_run_update_code.patch
patches.suse/tracing-snapshot-resize-spare-buffer-if-size-changed.patch
@@ -23297,6 +23319,7 @@
patches.fixes/PCI-Do-not-poll-for-PME-if-the-device-is-in-D3cold.patch
patches.drivers/cpufreq-brcmstb-avs-cpufreq-Fix-initial-command-chec.patch
patches.drivers/cpufreq-brcmstb-avs-cpufreq-Fix-types-for-voltage-fr.patch
+ patches.drivers/cpufreq-add-driver-for-raspberry-pi.patch
patches.suse/0023-bcache-don-t-set-max-writeback-rate-if-gc-is-running.patch
patches.suse/0024-bcache-check-c-gc_thread-by-IS_ERR_OR_NULL-in-cache_.patch
patches.suse/0025-bcache-fix-return-value-error-in-bch_journal_read.patch
@@ -23305,7 +23328,6 @@
patches.suse/0028-bcache-ignore-read-ahead-request-failure-on-backing-.patch
patches.suse/0029-bcache-add-io-error-counting-in-write_bdev_super_end.patch
patches.suse/0030-bcache-remove-unnecessary-prefetch-in-bset_search_tr.patch
- patches.suse/0031-bcache-use-sysfs_match_string-instead-of-__sysfs_mat.patch
patches.suse/0032-bcache-add-return-value-check-to-bch_cached_dev_run.patch
patches.suse/0033-bcache-remove-unncessary-code-in-bch_btree_keys_init.patch
patches.suse/0034-bcache-check-CACHE_SET_IO_DISABLE-in-allocator-code.patch
@@ -23437,6 +23459,10 @@
patches.drivers/dmaengine-hsu-Revert-set-HSU_CH_MTSR-to-memory-width.patch
patches.drivers/0008-dmaengine-rcar-dmac-Reject-zero-length-slave-DMA-req.patch
patches.drivers/clk-qcom-Fix-Wunused-const-variable.patch
+ patches.drivers/clk-bcm2835-remove-pllb.patch
+ patches.drivers/clk-bcm283x-add-driver-interfacing-with-raspberry-pi-s-firmware.patch
+ patches.drivers/firmware-raspberrypi-register-clk-device.patch
+ patches.drivers/clk-raspberrypi-register-platform-device-for-raspberrypi-cpufreq.patch
patches.drivers/clk-tegra210-fix-PLLU-and-PLLU_OUT1.patch
patches.drivers/clk-rockchip-Don-t-yell-about-bad-mmc-phases-when-ge.patch
patches.fixes/floppy-fix-div-by-zero-in-setup_format_params.patch
@@ -23453,6 +23479,7 @@
patches.fixes/crypto-ccp-gcm-use-const-time-tag-comparison.patch
patches.fixes/crypto-ccp-Fix-SEV_VERSION_GREATER_OR_EQUAL.patch
patches.drm/drm-nouveau-i2c-Enable-i2c-pads-busses-during-preini.patch
+ patches.drm/drm-nouveau-fix-memory-leak-in-nouveau_conn_reset.patch
patches.drivers/firmware-ti_sci-Always-request-response-from-firmwar.patch
patches.arch/kvm-svm-fix-detection-of-amd-errata-1096
patches.drivers/Input-synaptics-whitelist-Lenovo-T580-SMBus-intertou.patch
@@ -23493,6 +23520,7 @@
patches.drivers/ACPI-PM-Fix-regression-in-acpi_device_set_power.patch
patches.drivers/libata-zpodd-Fix-small-read-overflow-in-zpodd_get_me.patch
patches.drivers/ata-libahci-do-not-complain-in-case-of-deferred-prob.patch
+ patches.drm/drm-i915-userptr-Acquire-the-page-lock-around-set_pa.patch
patches.drivers/0013-HID-wacom-fix-bit-shift-for-Cintiq-Companion-2.patch
patches.drivers/hid-input-fix-a4tech-horizontal-wheel-custom-usage.patch
patches.fixes/bonding-Force-slave-speed-check-after-link-state-rec.patch
diff --git a/supported.conf b/supported.conf
index 76ce5db458..71f4ac968b 100644
--- a/supported.conf
+++ b/supported.conf
@@ -226,7 +226,6 @@
drivers/ata/ahci_platform
drivers/ata/ahci_seattle
- drivers/ata/ahci_tegra
- drivers/ata/libahci_platform
drivers/ata/ahci_xgene
drivers/ata/ata_generic
+base drivers/ata/ata_piix # SCSI low-level driver for Intel PIIX/ICH ATA controllers fate#303913
@@ -395,6 +394,7 @@
+external drivers/char/uv_mmtimer # SGI
+base drivers/char/virtio_console # fate#303913
drivers/char/xillybus/*
+ drivers/clk/bcm/clk-raspberrypi
drivers/clk/clk-rk808
- drivers/clk/*
drivers/cpufreq/acpi-cpufreq # x86 cpufreq driver used by all, if no specific one like intel_pstate
@@ -416,6 +416,7 @@
drivers/cpufreq/pcc-cpufreq # HP's PCC cpufreq driver -> fate#306746
drivers/cpufreq/powernow-k8 # Old AMD Athlon 64 and Opteron processor frequency driver,
# still supporting IO based switching. MSR based switching is done via acpi-cpufreq
+ drivers/cpufreq/raspberrypi-cpufreq
drivers/crypto/caam/*
drivers/crypto/ccp
drivers/crypto/ccp/ccp-crypto