From: Sasha Levin Date: Wed, 8 May 2019 20:23:45 +0000 (-0400) Subject: fixes for 5.0 X-Git-Tag: v4.9.175~36 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=64fefc3e8d70b3bc048ecf008b666774ddd4a3e1;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 5.0 Signed-off-by: Sasha Levin --- diff --git a/queue-5.0/alsa-hda-fix-racy-display-power-access.patch b/queue-5.0/alsa-hda-fix-racy-display-power-access.patch new file mode 100644 index 00000000000..7cda21b2810 --- /dev/null +++ b/queue-5.0/alsa-hda-fix-racy-display-power-access.patch @@ -0,0 +1,86 @@ +From ddbf91e855c58565f8942f2d22134bdfa7cfcc94 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 10 Apr 2019 12:49:55 +0200 +Subject: ALSA: hda: Fix racy display power access + +[ Upstream commit d7a181da2dfa3190487c446042ba01e07d851c74 ] + +snd_hdac_display_power() doesn't handle the concurrent calls carefully +enough, and it may lead to the doubly get_power or put_power calls, +when a runtime PM and an async work get called in racy way. + +This patch addresses it by reusing the bus->lock mutex that has been +used for protecting the link state change in ext bus code, so that it +can protect against racy display state changes. The initialization of +bus->lock was moved from snd_hdac_ext_bus_init() to +snd_hdac_bus_init() as well accordingly. + +Testcase: igt/i915_pm_rpm/module-reload #glk-dsi +Reported-by: Chris Wilson +Reviewed-by: Chris Wilson +Cc: Imre Deak +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/ext/hdac_ext_bus.c | 1 - + sound/hda/hdac_bus.c | 1 + + sound/hda/hdac_component.c | 6 +++++- + 3 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c +index 9c37d9af3023f..ec7715c6b0c02 100644 +--- a/sound/hda/ext/hdac_ext_bus.c ++++ b/sound/hda/ext/hdac_ext_bus.c +@@ -107,7 +107,6 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, + INIT_LIST_HEAD(&bus->hlink_list); + bus->idx = idx++; + +- mutex_init(&bus->lock); + bus->cmd_dma_state = true; + + return 0; +diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c +index 012305177f682..ad8eee08013fb 100644 +--- a/sound/hda/hdac_bus.c ++++ b/sound/hda/hdac_bus.c +@@ -38,6 +38,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, + INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events); + spin_lock_init(&bus->reg_lock); + mutex_init(&bus->cmd_mutex); ++ mutex_init(&bus->lock); + bus->irq = -1; + return 0; + } +diff --git a/sound/hda/hdac_component.c b/sound/hda/hdac_component.c +index a6d37b9d6413f..6b5caee61c6e0 100644 +--- a/sound/hda/hdac_component.c ++++ b/sound/hda/hdac_component.c +@@ -69,13 +69,15 @@ void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable) + + dev_dbg(bus->dev, "display power %s\n", + enable ? "enable" : "disable"); ++ ++ mutex_lock(&bus->lock); + if (enable) + set_bit(idx, &bus->display_power_status); + else + clear_bit(idx, &bus->display_power_status); + + if (!acomp || !acomp->ops) +- return; ++ goto unlock; + + if (bus->display_power_status) { + if (!bus->display_power_active) { +@@ -92,6 +94,8 @@ void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable) + bus->display_power_active = false; + } + } ++ unlock: ++ mutex_unlock(&bus->lock); + } + EXPORT_SYMBOL_GPL(snd_hdac_display_power); + +-- +2.20.1 + diff --git a/queue-5.0/asoc-cs35l35-disable-regulators-on-driver-removal.patch b/queue-5.0/asoc-cs35l35-disable-regulators-on-driver-removal.patch new file mode 100644 index 00000000000..ec76ea93ea1 --- /dev/null +++ b/queue-5.0/asoc-cs35l35-disable-regulators-on-driver-removal.patch @@ -0,0 +1,52 @@ +From ffe19ec75d5cd1b613e25f6b81dce788d4d5e8ea Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Thu, 4 Apr 2019 17:27:20 +0100 +Subject: ASoC: cs35l35: Disable regulators on driver removal + +[ Upstream commit 47c4cc08cb5b34e93ab337b924c5ede77ca3c936 ] + +The chips main power supplies VA and VP are enabled during probe but +then never disabled, this will cause warnings from the regulator +framework on driver removal. Fix this by adding a remove callback and +disabling the supplies, whilst doing so follow best practice and put the +chip back into reset as well. + +Signed-off-by: Charles Keepax +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/cs35l35.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c +index 9f4a59871cee7..c71696146c5ec 100644 +--- a/sound/soc/codecs/cs35l35.c ++++ b/sound/soc/codecs/cs35l35.c +@@ -1635,6 +1635,16 @@ static int cs35l35_i2c_probe(struct i2c_client *i2c_client, + return ret; + } + ++static int cs35l35_i2c_remove(struct i2c_client *i2c_client) ++{ ++ struct cs35l35_private *cs35l35 = i2c_get_clientdata(i2c_client); ++ ++ regulator_bulk_disable(cs35l35->num_supplies, cs35l35->supplies); ++ gpiod_set_value_cansleep(cs35l35->reset_gpio, 0); ++ ++ return 0; ++} ++ + static const struct of_device_id cs35l35_of_match[] = { + {.compatible = "cirrus,cs35l35"}, + {}, +@@ -1655,6 +1665,7 @@ static struct i2c_driver cs35l35_i2c_driver = { + }, + .id_table = cs35l35_id, + .probe = cs35l35_i2c_probe, ++ .remove = cs35l35_i2c_remove, + }; + + module_i2c_driver(cs35l35_i2c_driver); +-- +2.20.1 + diff --git a/queue-5.0/asoc-cs4270-set-auto-increment-bit-for-register-writ.patch b/queue-5.0/asoc-cs4270-set-auto-increment-bit-for-register-writ.patch new file mode 100644 index 00000000000..5c13a87d332 --- /dev/null +++ b/queue-5.0/asoc-cs4270-set-auto-increment-bit-for-register-writ.patch @@ -0,0 +1,37 @@ +From fc7b4f19a810b396d52384b3e17522175c25cba9 Mon Sep 17 00:00:00 2001 +From: Daniel Mack +Date: Wed, 20 Mar 2019 22:41:56 +0100 +Subject: ASoC: cs4270: Set auto-increment bit for register writes + +[ Upstream commit f0f2338a9cfaf71db895fa989ea7234e8a9b471d ] + +The CS4270 does not by default increment the register address on +consecutive writes. During normal operation it doesn't matter as all +register accesses are done individually. At resume time after suspend, +however, the regcache code gathers the biggest possible block of +registers to sync and sends them one on one go. + +To fix this, set the INCR bit in all cases. + +Signed-off-by: Daniel Mack +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/cs4270.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c +index 33d74f163bd75..793a14d586672 100644 +--- a/sound/soc/codecs/cs4270.c ++++ b/sound/soc/codecs/cs4270.c +@@ -642,6 +642,7 @@ static const struct regmap_config cs4270_regmap = { + .reg_defaults = cs4270_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults), + .cache_type = REGCACHE_RBTREE, ++ .write_flag_mask = CS4270_I2C_INCR, + + .readable_reg = cs4270_reg_is_readable, + .volatile_reg = cs4270_reg_is_volatile, +-- +2.20.1 + diff --git a/queue-5.0/asoc-dapm-fix-null-pointer-dereference-in-snd_soc_da.patch b/queue-5.0/asoc-dapm-fix-null-pointer-dereference-in-snd_soc_da.patch new file mode 100644 index 00000000000..2e6e5a16188 --- /dev/null +++ b/queue-5.0/asoc-dapm-fix-null-pointer-dereference-in-snd_soc_da.patch @@ -0,0 +1,37 @@ +From c4788065a2e5837a1ea21ffc2454a8203c22832f Mon Sep 17 00:00:00 2001 +From: Pankaj Bharadiya +Date: Fri, 22 Mar 2019 18:00:09 +0530 +Subject: ASoC: dapm: Fix NULL pointer dereference in + snd_soc_dapm_free_kcontrol + +[ Upstream commit cacea3a90e211f0c111975535508d446a4a928d2 ] + +w_text_param can be NULL and it is being dereferenced without checking. +Add the missing sanity check to prevent NULL pointer dereference. + +Signed-off-by: Pankaj Bharadiya +Acked-by: Pierre-Louis Bossart +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/soc-dapm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c +index 20bad755888b1..08ab5fef75dca 100644 +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -3840,6 +3840,10 @@ snd_soc_dapm_free_kcontrol(struct snd_soc_card *card, + int count; + + devm_kfree(card->dev, (void *)*private_value); ++ ++ if (!w_param_text) ++ return; ++ + for (count = 0 ; count < num_params; count++) + devm_kfree(card->dev, (void *)w_param_text[count]); + devm_kfree(card->dev, w_param_text); +-- +2.20.1 + diff --git a/queue-5.0/asoc-dpcm-prevent-snd_soc_dpcm-use-after-free.patch b/queue-5.0/asoc-dpcm-prevent-snd_soc_dpcm-use-after-free.patch new file mode 100644 index 00000000000..21e653e6ef9 --- /dev/null +++ b/queue-5.0/asoc-dpcm-prevent-snd_soc_dpcm-use-after-free.patch @@ -0,0 +1,277 @@ +From 425dd9d7f5643658d3de8d152cac75625e53182a Mon Sep 17 00:00:00 2001 +From: KaiChieh Chuang +Date: Fri, 8 Mar 2019 13:05:53 +0800 +Subject: ASoC: dpcm: prevent snd_soc_dpcm use after free + +[ Upstream commit a9764869779081e8bf24da07ac040e8f3efcf13a ] + +The dpcm get from fe_clients/be_clients +may be free before use + +Add a spin lock at snd_soc_card level, +to protect the dpcm instance. +The lock may be used in atomic context, so use spin lock. + +Use irq spin lock version, +since the lock may be used in interrupts. + +possible race condition between +void dpcm_be_disconnect( + ... + list_del(&dpcm->list_be); + list_del(&dpcm->list_fe); + kfree(dpcm); + ... + +and + for_each_dpcm_fe() + for_each_dpcm_be*() + +race condition example +Thread 1: + snd_soc_dapm_mixer_update_power() + -> soc_dpcm_runtime_update() + -> dpcm_be_disconnect() + -> kfree(dpcm); +Thread 2: + dpcm_fe_dai_trigger() + -> dpcm_be_dai_trigger() + -> snd_soc_dpcm_can_be_free_stop() + -> if (dpcm->fe == fe) + +Excpetion Scenario: + two FE link to same BE + FE1 -> BE + FE2 -> + + Thread 1: switch of mixer between FE2 -> BE + Thread 2: pcm_stop FE1 + +Exception: + +Unable to handle kernel paging request at virtual address dead0000000000e0 + +pc=<> [] dpcm_be_dai_trigger+0x29c/0x47c + sound/soc/soc-pcm.c:3226 + if (dpcm->fe == fe) +lr=<> [] dpcm_fe_dai_do_trigger+0x94/0x26c + +Backtrace: +[] notify_die+0x68/0xb8 +[] die+0x118/0x2a8 +[] __do_kernel_fault+0x13c/0x14c +[] do_translation_fault+0x64/0xa0 +[] do_mem_abort+0x4c/0xd0 +[] el1_da+0x24/0x40 +[] dpcm_be_dai_trigger+0x29c/0x47c +[] dpcm_fe_dai_do_trigger+0x94/0x26c +[] dpcm_fe_dai_trigger+0x3c/0x44 +[] snd_pcm_do_stop+0x50/0x5c +[] snd_pcm_action+0xb4/0x13c +[] snd_pcm_drop+0xa0/0x128 +[] snd_pcm_common_ioctl+0x9d8/0x30f0 +[] snd_pcm_ioctl_compat+0x29c/0x2f14 +[] compat_SyS_ioctl+0x128/0x244 +[] el0_svc_naked+0x34/0x38 +[] 0xffffffffffffffff + +Signed-off-by: KaiChieh Chuang +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + include/sound/soc.h | 2 ++ + sound/soc/soc-core.c | 1 + + sound/soc/soc-pcm.c | 40 +++++++++++++++++++++++++++++++++------- + 3 files changed, 36 insertions(+), 7 deletions(-) + +diff --git a/include/sound/soc.h b/include/sound/soc.h +index e665f111b0d27..fa82d62153287 100644 +--- a/include/sound/soc.h ++++ b/include/sound/soc.h +@@ -1043,6 +1043,8 @@ struct snd_soc_card { + struct mutex mutex; + struct mutex dapm_mutex; + ++ spinlock_t dpcm_lock; ++ + bool instantiated; + bool topology_shortname_created; + +diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c +index 50617db05c46b..416c371fa01a5 100644 +--- a/sound/soc/soc-core.c ++++ b/sound/soc/soc-core.c +@@ -2790,6 +2790,7 @@ int snd_soc_register_card(struct snd_soc_card *card) + card->instantiated = 0; + mutex_init(&card->mutex); + mutex_init(&card->dapm_mutex); ++ spin_lock_init(&card->dpcm_lock); + + return snd_soc_bind_card(card); + } +diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c +index fcdeffddbe46b..22946493a11fb 100644 +--- a/sound/soc/soc-pcm.c ++++ b/sound/soc/soc-pcm.c +@@ -1212,6 +1212,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, + struct snd_soc_pcm_runtime *be, int stream) + { + struct snd_soc_dpcm *dpcm; ++ unsigned long flags; + + /* only add new dpcms */ + for_each_dpcm_be(fe, stream, dpcm) { +@@ -1227,8 +1228,10 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, + dpcm->fe = fe; + be->dpcm[stream].runtime = fe->dpcm[stream].runtime; + dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW; ++ spin_lock_irqsave(&fe->card->dpcm_lock, flags); + list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients); + list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients); ++ spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + + dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n", + stream ? "capture" : "playback", fe->dai_link->name, +@@ -1274,6 +1277,7 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe, + void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) + { + struct snd_soc_dpcm *dpcm, *d; ++ unsigned long flags; + + for_each_dpcm_be_safe(fe, stream, dpcm, d) { + dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", +@@ -1293,8 +1297,10 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) + #ifdef CONFIG_DEBUG_FS + debugfs_remove(dpcm->debugfs_state); + #endif ++ spin_lock_irqsave(&fe->card->dpcm_lock, flags); + list_del(&dpcm->list_be); + list_del(&dpcm->list_fe); ++ spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + kfree(dpcm); + } + } +@@ -1546,10 +1552,13 @@ int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, + void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) + { + struct snd_soc_dpcm *dpcm; ++ unsigned long flags; + ++ spin_lock_irqsave(&fe->card->dpcm_lock, flags); + for_each_dpcm_be(fe, stream, dpcm) + dpcm->be->dpcm[stream].runtime_update = + SND_SOC_DPCM_UPDATE_NO; ++ spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + } + + static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe, +@@ -2575,6 +2584,7 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) + struct snd_soc_dpcm *dpcm; + enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; + int ret; ++ unsigned long flags; + + dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", + stream ? "capture" : "playback", fe->dai_link->name); +@@ -2644,11 +2654,13 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) + dpcm_be_dai_shutdown(fe, stream); + disconnect: + /* disconnect any non started BEs */ ++ spin_lock_irqsave(&fe->card->dpcm_lock, flags); + for_each_dpcm_be(fe, stream, dpcm) { + struct snd_soc_pcm_runtime *be = dpcm->be; + if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) + dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; + } ++ spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + + return ret; + } +@@ -3224,7 +3236,10 @@ int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, + { + struct snd_soc_dpcm *dpcm; + int state; ++ int ret = 1; ++ unsigned long flags; + ++ spin_lock_irqsave(&fe->card->dpcm_lock, flags); + for_each_dpcm_fe(be, stream, dpcm) { + + if (dpcm->fe == fe) +@@ -3233,12 +3248,15 @@ int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, + state = dpcm->fe->dpcm[stream].state; + if (state == SND_SOC_DPCM_STATE_START || + state == SND_SOC_DPCM_STATE_PAUSED || +- state == SND_SOC_DPCM_STATE_SUSPEND) +- return 0; ++ state == SND_SOC_DPCM_STATE_SUSPEND) { ++ ret = 0; ++ break; ++ } + } ++ spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + + /* it's safe to free/stop this BE DAI */ +- return 1; ++ return ret; + } + EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop); + +@@ -3251,7 +3269,10 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, + { + struct snd_soc_dpcm *dpcm; + int state; ++ int ret = 1; ++ unsigned long flags; + ++ spin_lock_irqsave(&fe->card->dpcm_lock, flags); + for_each_dpcm_fe(be, stream, dpcm) { + + if (dpcm->fe == fe) +@@ -3261,12 +3282,15 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, + if (state == SND_SOC_DPCM_STATE_START || + state == SND_SOC_DPCM_STATE_PAUSED || + state == SND_SOC_DPCM_STATE_SUSPEND || +- state == SND_SOC_DPCM_STATE_PREPARE) +- return 0; ++ state == SND_SOC_DPCM_STATE_PREPARE) { ++ ret = 0; ++ break; ++ } + } ++ spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + + /* it's safe to change hw_params */ +- return 1; ++ return ret; + } + EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); + +@@ -3305,6 +3329,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, + struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params; + struct snd_soc_dpcm *dpcm; + ssize_t offset = 0; ++ unsigned long flags; + + /* FE state */ + offset += snprintf(buf + offset, size - offset, +@@ -3332,6 +3357,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, + goto out; + } + ++ spin_lock_irqsave(&fe->card->dpcm_lock, flags); + for_each_dpcm_be(fe, stream, dpcm) { + struct snd_soc_pcm_runtime *be = dpcm->be; + params = &dpcm->hw_params; +@@ -3352,7 +3378,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, + params_channels(params), + params_rate(params)); + } +- ++ spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + out: + return offset; + } +-- +2.20.1 + diff --git a/queue-5.0/asoc-hdac_hda-use-correct-format-to-setup-hda-codec.patch b/queue-5.0/asoc-hdac_hda-use-correct-format-to-setup-hda-codec.patch new file mode 100644 index 00000000000..d3165621a07 --- /dev/null +++ b/queue-5.0/asoc-hdac_hda-use-correct-format-to-setup-hda-codec.patch @@ -0,0 +1,142 @@ +From 7913fb7b9401ea9ce8e727f15f778917b7f6f2ec Mon Sep 17 00:00:00 2001 +From: Rander Wang +Date: Fri, 8 Mar 2019 16:38:58 +0800 +Subject: ASoC:hdac_hda:use correct format to setup hda codec + +[ Upstream commit 03d0aa4d4fddce4a5d865d819a4d98bfc3d451e6 ] + +The current implementation of the hdac_hda codec results in zero-valued +samples on capture and noise with headset playback when SOF is used on +platforms with an on-board HDaudio codec. This is root-caused to SOF +using be_hw_params_fixup, and the prepare() call using invalid runtime +fields to determine the format. + +This patch moves the format handling to the hw_params() callback, as +done already for hdac_hdmi, to make sure the fixed-up information is +taken into account but keeps the codec initialization in prepare() as +the stream_tag is only available at that time. Moving everything in the +prepare() callback is possible but the code is less elegant so this +two-step solution was chosen. + +The solution was tested with the SST driver with no regressions, and all +the issues with SOF playback and capture are solved. + +Signed-off-by: Rander Wang +Acked-by: Pierre-Louis Bossart +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/hdac_hda.c | 53 +++++++++++++++++++++++++++---------- + sound/soc/codecs/hdac_hda.h | 1 + + 2 files changed, 40 insertions(+), 14 deletions(-) + +diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c +index ffecdaaa8cf2b..f889d94c8e3cf 100644 +--- a/sound/soc/codecs/hdac_hda.c ++++ b/sound/soc/codecs/hdac_hda.c +@@ -38,6 +38,9 @@ static void hdac_hda_dai_close(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai); + static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai); ++static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai); + static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai); + static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai, +@@ -50,6 +53,7 @@ static const struct snd_soc_dai_ops hdac_hda_dai_ops = { + .startup = hdac_hda_dai_open, + .shutdown = hdac_hda_dai_close, + .prepare = hdac_hda_dai_prepare, ++ .hw_params = hdac_hda_dai_hw_params, + .hw_free = hdac_hda_dai_hw_free, + .set_tdm_slot = hdac_hda_dai_set_tdm_slot, + }; +@@ -139,6 +143,39 @@ static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai, + return 0; + } + ++static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_component *component = dai->component; ++ struct hdac_hda_priv *hda_pvt; ++ unsigned int format_val; ++ unsigned int maxbps; ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ maxbps = dai->driver->playback.sig_bits; ++ else ++ maxbps = dai->driver->capture.sig_bits; ++ ++ hda_pvt = snd_soc_component_get_drvdata(component); ++ format_val = snd_hdac_calc_stream_format(params_rate(params), ++ params_channels(params), ++ params_format(params), ++ maxbps, ++ 0); ++ if (!format_val) { ++ dev_err(dai->dev, ++ "invalid format_val, rate=%d, ch=%d, format=%d, maxbps=%d\n", ++ params_rate(params), params_channels(params), ++ params_format(params), maxbps); ++ ++ return -EINVAL; ++ } ++ ++ hda_pvt->pcm[dai->id].format_val[substream->stream] = format_val; ++ return 0; ++} ++ + static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) + { +@@ -162,10 +199,9 @@ static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) + { + struct snd_soc_component *component = dai->component; ++ struct hda_pcm_stream *hda_stream; + struct hdac_hda_priv *hda_pvt; +- struct snd_pcm_runtime *runtime = substream->runtime; + struct hdac_device *hdev; +- struct hda_pcm_stream *hda_stream; + unsigned int format_val; + struct hda_pcm *pcm; + unsigned int stream; +@@ -179,19 +215,8 @@ static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, + + hda_stream = &pcm->stream[substream->stream]; + +- format_val = snd_hdac_calc_stream_format(runtime->rate, +- runtime->channels, +- runtime->format, +- hda_stream->maxbps, +- 0); +- if (!format_val) { +- dev_err(&hdev->dev, +- "invalid format_val, rate=%d, ch=%d, format=%d\n", +- runtime->rate, runtime->channels, runtime->format); +- return -EINVAL; +- } +- + stream = hda_pvt->pcm[dai->id].stream_tag[substream->stream]; ++ format_val = hda_pvt->pcm[dai->id].format_val[substream->stream]; + + ret = snd_hda_codec_prepare(&hda_pvt->codec, hda_stream, + stream, format_val, substream); +diff --git a/sound/soc/codecs/hdac_hda.h b/sound/soc/codecs/hdac_hda.h +index e444ef5933606..6b1bd4f428e70 100644 +--- a/sound/soc/codecs/hdac_hda.h ++++ b/sound/soc/codecs/hdac_hda.h +@@ -8,6 +8,7 @@ + + struct hdac_hda_pcm { + int stream_tag[2]; ++ unsigned int format_val[2]; + }; + + struct hdac_hda_priv { +-- +2.20.1 + diff --git a/queue-5.0/asoc-hdmi-codec-fix-s-pdif-dai.patch b/queue-5.0/asoc-hdmi-codec-fix-s-pdif-dai.patch new file mode 100644 index 00000000000..c11770d3291 --- /dev/null +++ b/queue-5.0/asoc-hdmi-codec-fix-s-pdif-dai.patch @@ -0,0 +1,176 @@ +From 56cd1822742c143f878d69deca2dec2b5db7d1e9 Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Thu, 28 Feb 2019 15:30:34 +0000 +Subject: ASoC: hdmi-codec: fix S/PDIF DAI + +[ Upstream commit 2e95f984aae4cf0608d0ba2189c756f2bd50b44a ] + +When using the S/PDIF DAI, there is no requirement to call +snd_soc_dai_set_fmt() as there is no DAI format definition that defines +S/PDIF. In any case, S/PDIF does not have separate clocks, this is +embedded into the data stream. + +Consequently, when attempting to use TDA998x in S/PDIF mode, the attempt +to configure TDA998x via the hw_params callback fails as the +hdmi_codec_daifmt is left initialised to zero. + +Since the S/PDIF DAI will only be used by S/PDIF, prepare the +hdmi_codec_daifmt structure for this format. + +Signed-off-by: Russell King +Reviewed-by: Jyri Sarha +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/hdmi-codec.c | 118 +++++++++++++++++----------------- + 1 file changed, 59 insertions(+), 59 deletions(-) + +diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c +index e5b6769b97977..d5f73c8372817 100644 +--- a/sound/soc/codecs/hdmi-codec.c ++++ b/sound/soc/codecs/hdmi-codec.c +@@ -529,73 +529,71 @@ static int hdmi_codec_set_fmt(struct snd_soc_dai *dai, + { + struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); + struct hdmi_codec_daifmt cf = { 0 }; +- int ret = 0; + + dev_dbg(dai->dev, "%s()\n", __func__); + +- if (dai->id == DAI_ID_SPDIF) { +- cf.fmt = HDMI_SPDIF; +- } else { +- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { +- case SND_SOC_DAIFMT_CBM_CFM: +- cf.bit_clk_master = 1; +- cf.frame_clk_master = 1; +- break; +- case SND_SOC_DAIFMT_CBS_CFM: +- cf.frame_clk_master = 1; +- break; +- case SND_SOC_DAIFMT_CBM_CFS: +- cf.bit_clk_master = 1; +- break; +- case SND_SOC_DAIFMT_CBS_CFS: +- break; +- default: +- return -EINVAL; +- } ++ if (dai->id == DAI_ID_SPDIF) ++ return 0; ++ ++ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBM_CFM: ++ cf.bit_clk_master = 1; ++ cf.frame_clk_master = 1; ++ break; ++ case SND_SOC_DAIFMT_CBS_CFM: ++ cf.frame_clk_master = 1; ++ break; ++ case SND_SOC_DAIFMT_CBM_CFS: ++ cf.bit_clk_master = 1; ++ break; ++ case SND_SOC_DAIFMT_CBS_CFS: ++ break; ++ default: ++ return -EINVAL; ++ } + +- switch (fmt & SND_SOC_DAIFMT_INV_MASK) { +- case SND_SOC_DAIFMT_NB_NF: +- break; +- case SND_SOC_DAIFMT_NB_IF: +- cf.frame_clk_inv = 1; +- break; +- case SND_SOC_DAIFMT_IB_NF: +- cf.bit_clk_inv = 1; +- break; +- case SND_SOC_DAIFMT_IB_IF: +- cf.frame_clk_inv = 1; +- cf.bit_clk_inv = 1; +- break; +- } ++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_NB_NF: ++ break; ++ case SND_SOC_DAIFMT_NB_IF: ++ cf.frame_clk_inv = 1; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ cf.bit_clk_inv = 1; ++ break; ++ case SND_SOC_DAIFMT_IB_IF: ++ cf.frame_clk_inv = 1; ++ cf.bit_clk_inv = 1; ++ break; ++ } + +- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { +- case SND_SOC_DAIFMT_I2S: +- cf.fmt = HDMI_I2S; +- break; +- case SND_SOC_DAIFMT_DSP_A: +- cf.fmt = HDMI_DSP_A; +- break; +- case SND_SOC_DAIFMT_DSP_B: +- cf.fmt = HDMI_DSP_B; +- break; +- case SND_SOC_DAIFMT_RIGHT_J: +- cf.fmt = HDMI_RIGHT_J; +- break; +- case SND_SOC_DAIFMT_LEFT_J: +- cf.fmt = HDMI_LEFT_J; +- break; +- case SND_SOC_DAIFMT_AC97: +- cf.fmt = HDMI_AC97; +- break; +- default: +- dev_err(dai->dev, "Invalid DAI interface format\n"); +- return -EINVAL; +- } ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ cf.fmt = HDMI_I2S; ++ break; ++ case SND_SOC_DAIFMT_DSP_A: ++ cf.fmt = HDMI_DSP_A; ++ break; ++ case SND_SOC_DAIFMT_DSP_B: ++ cf.fmt = HDMI_DSP_B; ++ break; ++ case SND_SOC_DAIFMT_RIGHT_J: ++ cf.fmt = HDMI_RIGHT_J; ++ break; ++ case SND_SOC_DAIFMT_LEFT_J: ++ cf.fmt = HDMI_LEFT_J; ++ break; ++ case SND_SOC_DAIFMT_AC97: ++ cf.fmt = HDMI_AC97; ++ break; ++ default: ++ dev_err(dai->dev, "Invalid DAI interface format\n"); ++ return -EINVAL; + } + + hcp->daifmt[dai->id] = cf; + +- return ret; ++ return 0; + } + + static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute) +@@ -792,8 +790,10 @@ static int hdmi_codec_probe(struct platform_device *pdev) + i++; + } + +- if (hcd->spdif) ++ if (hcd->spdif) { + hcp->daidrv[i] = hdmi_spdif_dai; ++ hcp->daifmt[DAI_ID_SPDIF].fmt = HDMI_SPDIF; ++ } + + dev_set_drvdata(dev, hcp); + +-- +2.20.1 + diff --git a/queue-5.0/asoc-intel-kbl-fix-wrong-number-of-channels.patch b/queue-5.0/asoc-intel-kbl-fix-wrong-number-of-channels.patch new file mode 100644 index 00000000000..ee030ce7f30 --- /dev/null +++ b/queue-5.0/asoc-intel-kbl-fix-wrong-number-of-channels.patch @@ -0,0 +1,34 @@ +From 96c064badadffd653da923bd8740b0b08a9f6039 Mon Sep 17 00:00:00 2001 +From: Tzung-Bi Shih +Date: Mon, 8 Apr 2019 17:08:58 +0800 +Subject: ASoC: Intel: kbl: fix wrong number of channels + +[ Upstream commit d6ba3f815bc5f3c4249d15c8bc5fbb012651b4a4 ] + +Fix wrong setting on number of channels. The context wants to set +constraint to 2 channels instead of 4. + +Signed-off-by: Tzung-Bi Shih +Acked-by: Pierre-Louis Bossart +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +index 7044d8c2b1873..879f14257a3ea 100644 +--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c ++++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +@@ -405,7 +405,7 @@ static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { + }; + + static const unsigned int dmic_2ch[] = { +- 4, ++ 2, + }; + + static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { +-- +2.20.1 + diff --git a/queue-5.0/asoc-intel-skl-fix-a-simultaneous-playback-capture-i.patch b/queue-5.0/asoc-intel-skl-fix-a-simultaneous-playback-capture-i.patch new file mode 100644 index 00000000000..7763544f280 --- /dev/null +++ b/queue-5.0/asoc-intel-skl-fix-a-simultaneous-playback-capture-i.patch @@ -0,0 +1,79 @@ +From 687651d2513b83aecea658529035db2b7f4686c3 Mon Sep 17 00:00:00 2001 +From: Rander Wang +Date: Fri, 8 Mar 2019 16:38:59 +0800 +Subject: ASoC:intel:skl:fix a simultaneous playback & capture issue on hda + platform + +[ Upstream commit c899df3e9b0bf7b76e642aed1a214582ea7012d5 ] + +If playback and capture are enabled concurrently, when the capture stops +the output becomes inaudile. The playback application will become stuck +and underrun after a timeout. + +This is caused by mistaken use of the stream_id, which should only be +set for playback and not for capture + +Tested on Apollolake and Kabylake with SST driver. + +Signed-off-by: Rander Wang +Acked-by: Pierre-Louis Bossart +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/skylake/skl-pcm.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c +index 557f80c0bfe53..5cd308d622f6e 100644 +--- a/sound/soc/intel/skylake/skl-pcm.c ++++ b/sound/soc/intel/skylake/skl-pcm.c +@@ -181,6 +181,7 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) + struct hdac_stream *hstream; + struct hdac_ext_stream *stream; + struct hdac_ext_link *link; ++ unsigned char stream_tag; + + hstream = snd_hdac_get_stream(bus, params->stream, + params->link_dma_id + 1); +@@ -199,10 +200,13 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) + + snd_hdac_ext_link_stream_setup(stream, format_val); + +- list_for_each_entry(link, &bus->hlink_list, list) { +- if (link->index == params->link_index) +- snd_hdac_ext_link_set_stream_id(link, +- hstream->stream_tag); ++ stream_tag = hstream->stream_tag; ++ if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) { ++ list_for_each_entry(link, &bus->hlink_list, list) { ++ if (link->index == params->link_index) ++ snd_hdac_ext_link_set_stream_id(link, ++ stream_tag); ++ } + } + + stream->link_prepared = 1; +@@ -645,6 +649,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, + struct hdac_ext_stream *link_dev = + snd_soc_dai_get_dma_data(dai, substream); + struct hdac_ext_link *link; ++ unsigned char stream_tag; + + dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); + +@@ -654,7 +659,11 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, + if (!link) + return -EINVAL; + +- snd_hdac_ext_link_clear_stream_id(link, hdac_stream(link_dev)->stream_tag); ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ stream_tag = hdac_stream(link_dev)->stream_tag; ++ snd_hdac_ext_link_clear_stream_id(link, stream_tag); ++ } ++ + snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK); + return 0; + } +-- +2.20.1 + diff --git a/queue-5.0/asoc-nau8810-fix-the-issue-of-widget-with-prefixed-n.patch b/queue-5.0/asoc-nau8810-fix-the-issue-of-widget-with-prefixed-n.patch new file mode 100644 index 00000000000..a112d9ea410 --- /dev/null +++ b/queue-5.0/asoc-nau8810-fix-the-issue-of-widget-with-prefixed-n.patch @@ -0,0 +1,37 @@ +From 0be90df00562c8162ab1e476390eca7e7f61a10f Mon Sep 17 00:00:00 2001 +From: John Hsu +Date: Wed, 13 Mar 2019 16:23:44 +0800 +Subject: ASoC: nau8810: fix the issue of widget with prefixed name + +[ Upstream commit 54d1cf78b0f4ba348a7c7fb8b7d0708d71b6cc8a ] + +The driver changes the stream name of DAC and ADC to avoid the issue of +widget with prefixed name. When the machine adds prefixed name for codec, +the stream name of DAI may not find the widgets. + +Signed-off-by: John Hsu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/nau8810.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c +index bfd74b86c9d2f..645aa07941237 100644 +--- a/sound/soc/codecs/nau8810.c ++++ b/sound/soc/codecs/nau8810.c +@@ -411,9 +411,9 @@ static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = { + SND_SOC_DAPM_MIXER("Mono Mixer", NAU8810_REG_POWER3, + NAU8810_MOUTMX_EN_SFT, 0, &nau8810_mono_mixer_controls[0], + ARRAY_SIZE(nau8810_mono_mixer_controls)), +- SND_SOC_DAPM_DAC("DAC", "HiFi Playback", NAU8810_REG_POWER3, ++ SND_SOC_DAPM_DAC("DAC", "Playback", NAU8810_REG_POWER3, + NAU8810_DAC_EN_SFT, 0), +- SND_SOC_DAPM_ADC("ADC", "HiFi Capture", NAU8810_REG_POWER2, ++ SND_SOC_DAPM_ADC("ADC", "Capture", NAU8810_REG_POWER2, + NAU8810_ADC_EN_SFT, 0), + SND_SOC_DAPM_PGA("SpkN Out", NAU8810_REG_POWER3, + NAU8810_NSPK_EN_SFT, 0, NULL, 0), +-- +2.20.1 + diff --git a/queue-5.0/asoc-nau8824-fix-the-issue-of-the-widget-with-prefix.patch b/queue-5.0/asoc-nau8824-fix-the-issue-of-the-widget-with-prefix.patch new file mode 100644 index 00000000000..3e074c0a52a --- /dev/null +++ b/queue-5.0/asoc-nau8824-fix-the-issue-of-the-widget-with-prefix.patch @@ -0,0 +1,108 @@ +From 9273d4c1ea753488dc208dad8fd39a4e0c716525 Mon Sep 17 00:00:00 2001 +From: John Hsu +Date: Mon, 11 Mar 2019 09:36:45 +0800 +Subject: ASoC: nau8824: fix the issue of the widget with prefix name + +[ Upstream commit 844a4a362dbec166b44d6b9b3dd45b08cb273703 ] + +The driver has two issues when machine add prefix name for codec. +(1)The stream name of DAI can't find the AIF widgets. +(2)The drivr can enable/disalbe the MICBIAS and SAR widgets. + +The patch will fix these issues caused by prefixed name added. + +Signed-off-by: John Hsu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/nau8824.c | 46 +++++++++++++++++++++++++++++++------- + 1 file changed, 38 insertions(+), 8 deletions(-) + +diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c +index 468d5143e2c4f..663a208c2f784 100644 +--- a/sound/soc/codecs/nau8824.c ++++ b/sound/soc/codecs/nau8824.c +@@ -681,8 +681,8 @@ static const struct snd_soc_dapm_widget nau8824_dapm_widgets[] = { + SND_SOC_DAPM_ADC("ADCR", NULL, NAU8824_REG_ANALOG_ADC_2, + NAU8824_ADCR_EN_SFT, 0), + +- SND_SOC_DAPM_AIF_OUT("AIFTX", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0), +- SND_SOC_DAPM_AIF_IN("AIFRX", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0), ++ SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0), ++ SND_SOC_DAPM_AIF_IN("AIFRX", "Playback", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_DAC("DACL", NULL, NAU8824_REG_RDAC, + NAU8824_DACL_EN_SFT, 0), +@@ -831,6 +831,36 @@ static void nau8824_int_status_clear_all(struct regmap *regmap) + } + } + ++static void nau8824_dapm_disable_pin(struct nau8824 *nau8824, const char *pin) ++{ ++ struct snd_soc_dapm_context *dapm = nau8824->dapm; ++ const char *prefix = dapm->component->name_prefix; ++ char prefixed_pin[80]; ++ ++ if (prefix) { ++ snprintf(prefixed_pin, sizeof(prefixed_pin), "%s %s", ++ prefix, pin); ++ snd_soc_dapm_disable_pin(dapm, prefixed_pin); ++ } else { ++ snd_soc_dapm_disable_pin(dapm, pin); ++ } ++} ++ ++static void nau8824_dapm_enable_pin(struct nau8824 *nau8824, const char *pin) ++{ ++ struct snd_soc_dapm_context *dapm = nau8824->dapm; ++ const char *prefix = dapm->component->name_prefix; ++ char prefixed_pin[80]; ++ ++ if (prefix) { ++ snprintf(prefixed_pin, sizeof(prefixed_pin), "%s %s", ++ prefix, pin); ++ snd_soc_dapm_force_enable_pin(dapm, prefixed_pin); ++ } else { ++ snd_soc_dapm_force_enable_pin(dapm, pin); ++ } ++} ++ + static void nau8824_eject_jack(struct nau8824 *nau8824) + { + struct snd_soc_dapm_context *dapm = nau8824->dapm; +@@ -839,8 +869,8 @@ static void nau8824_eject_jack(struct nau8824 *nau8824) + /* Clear all interruption status */ + nau8824_int_status_clear_all(regmap); + +- snd_soc_dapm_disable_pin(dapm, "SAR"); +- snd_soc_dapm_disable_pin(dapm, "MICBIAS"); ++ nau8824_dapm_disable_pin(nau8824, "SAR"); ++ nau8824_dapm_disable_pin(nau8824, "MICBIAS"); + snd_soc_dapm_sync(dapm); + + /* Enable the insertion interruption, disable the ejection +@@ -870,8 +900,8 @@ static void nau8824_jdet_work(struct work_struct *work) + struct regmap *regmap = nau8824->regmap; + int adc_value, event = 0, event_mask = 0; + +- snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); +- snd_soc_dapm_force_enable_pin(dapm, "SAR"); ++ nau8824_dapm_enable_pin(nau8824, "MICBIAS"); ++ nau8824_dapm_enable_pin(nau8824, "SAR"); + snd_soc_dapm_sync(dapm); + + msleep(100); +@@ -882,8 +912,8 @@ static void nau8824_jdet_work(struct work_struct *work) + if (adc_value < HEADSET_SARADC_THD) { + event |= SND_JACK_HEADPHONE; + +- snd_soc_dapm_disable_pin(dapm, "SAR"); +- snd_soc_dapm_disable_pin(dapm, "MICBIAS"); ++ nau8824_dapm_disable_pin(nau8824, "SAR"); ++ nau8824_dapm_disable_pin(nau8824, "MICBIAS"); + snd_soc_dapm_sync(dapm); + } else { + event |= SND_JACK_HEADSET; +-- +2.20.1 + diff --git a/queue-5.0/asoc-rockchip-pdm-fix-regmap_ops-hang-issue.patch b/queue-5.0/asoc-rockchip-pdm-fix-regmap_ops-hang-issue.patch new file mode 100644 index 00000000000..8f6f0ae22af --- /dev/null +++ b/queue-5.0/asoc-rockchip-pdm-fix-regmap_ops-hang-issue.patch @@ -0,0 +1,35 @@ +From a60e45dad5fbb26381928f762559447f2ea90b16 Mon Sep 17 00:00:00 2001 +From: Sugar Zhang +Date: Wed, 3 Apr 2019 21:40:45 +0800 +Subject: ASoC: rockchip: pdm: fix regmap_ops hang issue + +[ Upstream commit c85064435fe7a216ec0f0238ef2b8f7cd850a450 ] + +This is because set_fmt ops maybe called when PD is off, +and in such case, regmap_ops will lead system hang. +enale PD before doing regmap_ops. + +Signed-off-by: Sugar Zhang +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/rockchip/rockchip_pdm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c +index 400e29edb1c9c..8a2e3bbce3a16 100644 +--- a/sound/soc/rockchip/rockchip_pdm.c ++++ b/sound/soc/rockchip/rockchip_pdm.c +@@ -208,7 +208,9 @@ static int rockchip_pdm_set_fmt(struct snd_soc_dai *cpu_dai, + return -EINVAL; + } + ++ pm_runtime_get_sync(cpu_dai->dev); + regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, mask, val); ++ pm_runtime_put(cpu_dai->dev); + + return 0; + } +-- +2.20.1 + diff --git a/queue-5.0/asoc-rt5682-check-jd-status-when-system-resume.patch b/queue-5.0/asoc-rt5682-check-jd-status-when-system-resume.patch new file mode 100644 index 00000000000..59f4995ebf6 --- /dev/null +++ b/queue-5.0/asoc-rt5682-check-jd-status-when-system-resume.patch @@ -0,0 +1,119 @@ +From 5dd8dbf487d168b3ab9a95b66b4ab46c59cc8cf3 Mon Sep 17 00:00:00 2001 +From: Shuming Fan +Date: Fri, 8 Mar 2019 11:36:08 +0800 +Subject: ASoC: rt5682: Check JD status when system resume + +[ Upstream commit 4834d7070c85a5fb69637265dbbb05d13043280c ] + +The IRQ function may not work when system suspend. +We remove snd_soc_dapm_force_enable_pin function call to +make sure the bias off when idle and run into suspend/resume function. + +Signed-off-by: Shuming Fan +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/rt5682.c | 34 +++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c +index a9b91bcfcc096..49ff5e52db584 100644 +--- a/sound/soc/codecs/rt5682.c ++++ b/sound/soc/codecs/rt5682.c +@@ -904,13 +904,20 @@ static int rt5682_headset_detect(struct snd_soc_component *component, + int jack_insert) + { + struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); +- struct snd_soc_dapm_context *dapm = +- snd_soc_component_get_dapm(component); + unsigned int val, count; + + if (jack_insert) { +- snd_soc_dapm_force_enable_pin(dapm, "CBJ Power"); +- snd_soc_dapm_sync(dapm); ++ ++ snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, ++ RT5682_PWR_VREF2, RT5682_PWR_VREF2); ++ snd_soc_component_update_bits(component, ++ RT5682_PWR_ANLG_1, RT5682_PWR_FV2, 0); ++ usleep_range(15000, 20000); ++ snd_soc_component_update_bits(component, ++ RT5682_PWR_ANLG_1, RT5682_PWR_FV2, RT5682_PWR_FV2); ++ snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, ++ RT5682_PWR_CBJ, RT5682_PWR_CBJ); ++ + snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, + RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_HIGH); + +@@ -938,8 +945,10 @@ static int rt5682_headset_detect(struct snd_soc_component *component, + rt5682_enable_push_button_irq(component, false); + snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, + RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); +- snd_soc_dapm_disable_pin(dapm, "CBJ Power"); +- snd_soc_dapm_sync(dapm); ++ snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, ++ RT5682_PWR_VREF2, 0); ++ snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, ++ RT5682_PWR_CBJ, 0); + + rt5682->jack_type = 0; + } +@@ -1585,8 +1594,6 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { + 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0, + rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), +- SND_SOC_DAPM_SUPPLY("Vref2", RT5682_PWR_ANLG_1, RT5682_PWR_VREF2_BIT, 0, +- rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), + + /* ASRC */ + SND_SOC_DAPM_SUPPLY_S("DAC STO1 ASRC", 1, RT5682_PLL_TRACK_1, +@@ -1621,9 +1628,6 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { + SND_SOC_DAPM_PGA("BST1 CBJ", SND_SOC_NOPM, + 0, 0, NULL, 0), + +- SND_SOC_DAPM_SUPPLY("CBJ Power", RT5682_PWR_ANLG_3, +- RT5682_PWR_CBJ_BIT, 0, NULL, 0), +- + /* REC Mixer */ + SND_SOC_DAPM_MIXER("RECMIX1L", SND_SOC_NOPM, 0, 0, rt5682_rec1_l_mix, + ARRAY_SIZE(rt5682_rec1_l_mix)), +@@ -1786,17 +1790,13 @@ static const struct snd_soc_dapm_route rt5682_dapm_routes[] = { + + /*Vref*/ + {"MICBIAS1", NULL, "Vref1"}, +- {"MICBIAS1", NULL, "Vref2"}, + {"MICBIAS2", NULL, "Vref1"}, +- {"MICBIAS2", NULL, "Vref2"}, + + {"CLKDET SYS", NULL, "CLKDET"}, + + {"IN1P", NULL, "LDO2"}, + + {"BST1 CBJ", NULL, "IN1P"}, +- {"BST1 CBJ", NULL, "CBJ Power"}, +- {"CBJ Power", NULL, "Vref2"}, + + {"RECMIX1L", "CBJ Switch", "BST1 CBJ"}, + {"RECMIX1L", NULL, "RECMIX1L Power"}, +@@ -1906,9 +1906,7 @@ static const struct snd_soc_dapm_route rt5682_dapm_routes[] = { + {"HP Amp", NULL, "Capless"}, + {"HP Amp", NULL, "Charge Pump"}, + {"HP Amp", NULL, "CLKDET SYS"}, +- {"HP Amp", NULL, "CBJ Power"}, + {"HP Amp", NULL, "Vref1"}, +- {"HP Amp", NULL, "Vref2"}, + {"HPOL Playback", "Switch", "HP Amp"}, + {"HPOR Playback", "Switch", "HP Amp"}, + {"HPOL", NULL, "HPOL Playback"}, +@@ -2357,6 +2355,8 @@ static int rt5682_resume(struct snd_soc_component *component) + regcache_cache_only(rt5682->regmap, false); + regcache_sync(rt5682->regmap); + ++ rt5682_irq(0, rt5682); ++ + return 0; + } + #else +-- +2.20.1 + diff --git a/queue-5.0/asoc-rt5682-fix-jack-type-detection-issue.patch b/queue-5.0/asoc-rt5682-fix-jack-type-detection-issue.patch new file mode 100644 index 00000000000..593b52d8d52 --- /dev/null +++ b/queue-5.0/asoc-rt5682-fix-jack-type-detection-issue.patch @@ -0,0 +1,70 @@ +From a2ef174e19bd7947f4a4c4c1838a77bda342e249 Mon Sep 17 00:00:00 2001 +From: Shuming Fan +Date: Mon, 18 Mar 2019 15:17:13 +0800 +Subject: ASoC: rt5682: fix jack type detection issue + +[ Upstream commit 675212bfb23394514b7f68ebf3954ba936281ccc ] + +The jack type detection needs the main bias power of analog. +The modification makes sure the main bias power on/off while jack plug/unplug. + +Signed-off-by: Shuming Fan +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/rt5682.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c +index 49ff5e52db584..9331c13d2017a 100644 +--- a/sound/soc/codecs/rt5682.c ++++ b/sound/soc/codecs/rt5682.c +@@ -909,7 +909,8 @@ static int rt5682_headset_detect(struct snd_soc_component *component, + if (jack_insert) { + + snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, +- RT5682_PWR_VREF2, RT5682_PWR_VREF2); ++ RT5682_PWR_VREF2 | RT5682_PWR_MB, ++ RT5682_PWR_VREF2 | RT5682_PWR_MB); + snd_soc_component_update_bits(component, + RT5682_PWR_ANLG_1, RT5682_PWR_FV2, 0); + usleep_range(15000, 20000); +@@ -946,7 +947,7 @@ static int rt5682_headset_detect(struct snd_soc_component *component, + snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, + RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); + snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, +- RT5682_PWR_VREF2, 0); ++ RT5682_PWR_VREF2 | RT5682_PWR_MB, 0); + snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, + RT5682_PWR_CBJ, 0); + +@@ -2295,16 +2296,13 @@ static int rt5682_set_bias_level(struct snd_soc_component *component, + switch (level) { + case SND_SOC_BIAS_PREPARE: + regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, +- RT5682_PWR_MB | RT5682_PWR_BG, +- RT5682_PWR_MB | RT5682_PWR_BG); ++ RT5682_PWR_BG, RT5682_PWR_BG); + regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, + RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO, + RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO); + break; + + case SND_SOC_BIAS_STANDBY: +- regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, +- RT5682_PWR_MB, RT5682_PWR_MB); + regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, + RT5682_DIG_GATE_CTRL, RT5682_DIG_GATE_CTRL); + break; +@@ -2312,7 +2310,7 @@ static int rt5682_set_bias_level(struct snd_soc_component *component, + regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, + RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO, 0); + regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, +- RT5682_PWR_MB | RT5682_PWR_BG, 0); ++ RT5682_PWR_BG, 0); + break; + + default: +-- +2.20.1 + diff --git a/queue-5.0/asoc-rt5682-recording-has-no-sound-after-booting.patch b/queue-5.0/asoc-rt5682-recording-has-no-sound-after-booting.patch new file mode 100644 index 00000000000..baa4b619322 --- /dev/null +++ b/queue-5.0/asoc-rt5682-recording-has-no-sound-after-booting.patch @@ -0,0 +1,62 @@ +From 9247a90df23408012216b3354c08f62fcf1519ee Mon Sep 17 00:00:00 2001 +From: Shuming Fan +Date: Mon, 18 Mar 2019 15:17:42 +0800 +Subject: ASoC: rt5682: recording has no sound after booting + +[ Upstream commit 1c5b6a27e432e4fe170a924c8b41012271496a4c ] + +If ASRC turns on, HW will use clk_dac as the reference clock +whether recording or playback. +Both of clk_dac and clk_adc should set proper clock while using ASRC. + +Signed-off-by: Shuming Fan +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/rt5682.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c +index 9331c13d2017a..72ef2a0f6387d 100644 +--- a/sound/soc/codecs/rt5682.c ++++ b/sound/soc/codecs/rt5682.c +@@ -1202,7 +1202,7 @@ static int set_filter_clk(struct snd_soc_dapm_widget *w, + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); +- int ref, val, reg, sft, mask, idx = -EINVAL; ++ int ref, val, reg, idx = -EINVAL; + static const int div_f[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48}; + static const int div_o[] = {1, 2, 4, 6, 8, 12, 16, 24, 32, 48}; + +@@ -1216,15 +1216,10 @@ static int set_filter_clk(struct snd_soc_dapm_widget *w, + + idx = rt5682_div_sel(rt5682, ref, div_f, ARRAY_SIZE(div_f)); + +- if (w->shift == RT5682_PWR_ADC_S1F_BIT) { ++ if (w->shift == RT5682_PWR_ADC_S1F_BIT) + reg = RT5682_PLL_TRACK_3; +- sft = RT5682_ADC_OSR_SFT; +- mask = RT5682_ADC_OSR_MASK; +- } else { ++ else + reg = RT5682_PLL_TRACK_2; +- sft = RT5682_DAC_OSR_SFT; +- mask = RT5682_DAC_OSR_MASK; +- } + + snd_soc_component_update_bits(component, reg, + RT5682_FILTER_CLK_DIV_MASK, idx << RT5682_FILTER_CLK_DIV_SFT); +@@ -1236,7 +1231,8 @@ static int set_filter_clk(struct snd_soc_dapm_widget *w, + } + + snd_soc_component_update_bits(component, RT5682_ADDA_CLK_1, +- mask, idx << sft); ++ RT5682_ADC_OSR_MASK | RT5682_DAC_OSR_MASK, ++ (idx << RT5682_ADC_OSR_SFT) | (idx << RT5682_DAC_OSR_SFT)); + + return 0; + } +-- +2.20.1 + diff --git a/queue-5.0/asoc-samsung-odroid-fix-clock-configuration-for-4410.patch b/queue-5.0/asoc-samsung-odroid-fix-clock-configuration-for-4410.patch new file mode 100644 index 00000000000..962c6f99ad6 --- /dev/null +++ b/queue-5.0/asoc-samsung-odroid-fix-clock-configuration-for-4410.patch @@ -0,0 +1,47 @@ +From b78c7241ad65e7d349a5e5cb1c44105dfd99a9cf Mon Sep 17 00:00:00 2001 +From: Sylwester Nawrocki +Date: Tue, 12 Mar 2019 18:40:06 +0100 +Subject: ASoC: samsung: odroid: Fix clock configuration for 44100 sample rate + +[ Upstream commit 2b13bee3884926cba22061efa75bd315e871de24 ] + +After commit fbeec965b8d1c ("ASoC: samsung: odroid: Fix 32000 sample rate +handling") the audio root clock frequency is configured improperly for +44100 sample rate. Due to clock rate rounding it's 20070401 Hz instead +of 22579000 Hz. This results in a too low value of the PSR clock divider +in the CPU DAI driver and too fast actual sample rate for fs=44100. E.g. +1 kHz tone has actual 1780 Hz frequency (1 kHz * 20070401/22579000 * 2). + +Fix this by increasing the correction passed to clk_set_rate() to take +into account inaccuracy of the EPLL frequency properly. + +Fixes: fbeec965b8d1c ("ASoC: samsung: odroid: Fix 32000 sample rate handling") +Reported-by: JaeChul Lee +Signed-off-by: Sylwester Nawrocki +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/samsung/odroid.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c +index e7b371b072304..45c6d73967852 100644 +--- a/sound/soc/samsung/odroid.c ++++ b/sound/soc/samsung/odroid.c +@@ -64,11 +64,11 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream, + return ret; + + /* +- * We add 1 to the rclk_freq value in order to avoid too low clock ++ * We add 2 to the rclk_freq value in order to avoid too low clock + * frequency values due to the EPLL output frequency not being exact + * multiple of the audio sampling rate. + */ +- rclk_freq = params_rate(params) * rfs + 1; ++ rclk_freq = params_rate(params) * rfs + 2; + + ret = clk_set_rate(priv->sclk_i2s, rclk_freq); + if (ret < 0) +-- +2.20.1 + diff --git a/queue-5.0/asoc-soc-pcm-fix-a-codec-fixup-issue-in-tdm-case.patch b/queue-5.0/asoc-soc-pcm-fix-a-codec-fixup-issue-in-tdm-case.patch new file mode 100644 index 00000000000..28bfb9c6754 --- /dev/null +++ b/queue-5.0/asoc-soc-pcm-fix-a-codec-fixup-issue-in-tdm-case.patch @@ -0,0 +1,62 @@ +From 01622c3e8de58434b4fa80b7e30370dc6f50bb59 Mon Sep 17 00:00:00 2001 +From: Rander Wang +Date: Fri, 8 Mar 2019 16:38:57 +0800 +Subject: ASoC:soc-pcm:fix a codec fixup issue in TDM case + +[ Upstream commit 570f18b6a8d1f0e60e8caf30e66161b6438dcc91 ] + +On HDaudio platforms, if playback is started when capture is working, +there is no audible output. + +This can be root-caused to the use of the rx|tx_mask to store an HDaudio +stream tag. + +If capture is stared before playback, rx_mask would be non-zero on HDaudio +platform, then the channel number of playback, which is in the same codec +dai with the capture, would be changed by soc_pcm_codec_params_fixup based +on the tx_mask at first, then overwritten by this function based on rx_mask +at last. + +According to the author of tx|rx_mask, tx_mask is for playback and rx_mask +is for capture. And stream direction is checked at all other references of +tx|rx_mask in ASoC, so here should be an error. This patch checks stream +direction for tx|rx_mask for fixup function. + +This issue would affect not only HDaudio+ASoC, but also I2S codecs if the +channel number based on rx_mask is not equal to the one for tx_mask. It could +be rarely reproduecd because most drivers in kernel set the same channel number +to tx|rx_mask or rx_mask is zero. + +Tested on all platforms using stream_tag & HDaudio and intel I2S platforms. + +Signed-off-by: Rander Wang +Acked-by: Pierre-Louis Bossart +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/soc-pcm.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c +index 0c1dd6bd67abc..fcdeffddbe46b 100644 +--- a/sound/soc/soc-pcm.c ++++ b/sound/soc/soc-pcm.c +@@ -954,10 +954,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, + codec_params = *params; + + /* fixup params based on TDM slot masks */ +- if (codec_dai->tx_mask) ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && ++ codec_dai->tx_mask) + soc_pcm_codec_params_fixup(&codec_params, + codec_dai->tx_mask); +- if (codec_dai->rx_mask) ++ ++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && ++ codec_dai->rx_mask) + soc_pcm_codec_params_fixup(&codec_params, + codec_dai->rx_mask); + +-- +2.20.1 + diff --git a/queue-5.0/asoc-stm32-dfsdm-fix-debugfs-warnings-on-entry-creat.patch b/queue-5.0/asoc-stm32-dfsdm-fix-debugfs-warnings-on-entry-creat.patch new file mode 100644 index 00000000000..8d992c7e5bd --- /dev/null +++ b/queue-5.0/asoc-stm32-dfsdm-fix-debugfs-warnings-on-entry-creat.patch @@ -0,0 +1,73 @@ +From 1a6d011f705028066aad8771ad3eab5f57dbdbf4 Mon Sep 17 00:00:00 2001 +From: Olivier Moysan +Date: Mon, 4 Mar 2019 15:52:44 +0100 +Subject: ASoC: stm32: dfsdm: fix debugfs warnings on entry creation + +[ Upstream commit c47255b61129857b74b0d86eaf59335348be05e0 ] + +Register platform component with a prefix, to avoid warnings +on debugfs entries creation, due to component name +redundancy. + +Signed-off-by: Olivier Moysan +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/stm/stm32_adfsdm.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c +index 71d341b732a4d..24948b95eb19f 100644 +--- a/sound/soc/stm/stm32_adfsdm.c ++++ b/sound/soc/stm/stm32_adfsdm.c +@@ -304,6 +304,7 @@ MODULE_DEVICE_TABLE(of, stm32_adfsdm_of_match); + static int stm32_adfsdm_probe(struct platform_device *pdev) + { + struct stm32_adfsdm_priv *priv; ++ struct snd_soc_component *component; + int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); +@@ -331,9 +332,15 @@ static int stm32_adfsdm_probe(struct platform_device *pdev) + if (IS_ERR(priv->iio_cb)) + return PTR_ERR(priv->iio_cb); + +- ret = devm_snd_soc_register_component(&pdev->dev, +- &stm32_adfsdm_soc_platform, +- NULL, 0); ++ component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL); ++ if (!component) ++ return -ENOMEM; ++#ifdef CONFIG_DEBUG_FS ++ component->debugfs_prefix = "pcm"; ++#endif ++ ++ ret = snd_soc_add_component(&pdev->dev, component, ++ &stm32_adfsdm_soc_platform, NULL, 0); + if (ret < 0) + dev_err(&pdev->dev, "%s: Failed to register PCM platform\n", + __func__); +@@ -341,12 +348,20 @@ static int stm32_adfsdm_probe(struct platform_device *pdev) + return ret; + } + ++static int stm32_adfsdm_remove(struct platform_device *pdev) ++{ ++ snd_soc_unregister_component(&pdev->dev); ++ ++ return 0; ++} ++ + static struct platform_driver stm32_adfsdm_driver = { + .driver = { + .name = STM32_ADFSDM_DRV_NAME, + .of_match_table = stm32_adfsdm_of_match, + }, + .probe = stm32_adfsdm_probe, ++ .remove = stm32_adfsdm_remove, + }; + + module_platform_driver(stm32_adfsdm_driver); +-- +2.20.1 + diff --git a/queue-5.0/asoc-stm32-dfsdm-manage-multiple-prepare.patch b/queue-5.0/asoc-stm32-dfsdm-manage-multiple-prepare.patch new file mode 100644 index 00000000000..7b86858c0a5 --- /dev/null +++ b/queue-5.0/asoc-stm32-dfsdm-manage-multiple-prepare.patch @@ -0,0 +1,94 @@ +From c26f65d535f72a1cbccb389c2bd6a2f39ff695fd Mon Sep 17 00:00:00 2001 +From: Olivier Moysan +Date: Mon, 4 Mar 2019 15:52:43 +0100 +Subject: ASoC: stm32: dfsdm: manage multiple prepare + +[ Upstream commit 19441e35a43b616ea6afad91ed0d9e77268d8f6a ] + +The DFSDM must be stopped when a new setting is applied. +restart systematically DFSDM on multiple prepare calls, +to apply changes. + +Signed-off-by: Olivier Moysan +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/stm/stm32_adfsdm.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c +index 706ff005234f3..71d341b732a4d 100644 +--- a/sound/soc/stm/stm32_adfsdm.c ++++ b/sound/soc/stm/stm32_adfsdm.c +@@ -9,6 +9,7 @@ + + #include + #include ++#include + #include + #include + +@@ -37,6 +38,8 @@ struct stm32_adfsdm_priv { + /* PCM buffer */ + unsigned char *pcm_buff; + unsigned int pos; ++ ++ struct mutex lock; /* protect against race condition on iio state */ + }; + + static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = { +@@ -62,10 +65,12 @@ static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream, + { + struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); + ++ mutex_lock(&priv->lock); + if (priv->iio_active) { + iio_channel_stop_all_cb(priv->iio_cb); + priv->iio_active = false; + } ++ mutex_unlock(&priv->lock); + } + + static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, +@@ -74,13 +79,19 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, + struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); + int ret; + ++ mutex_lock(&priv->lock); ++ if (priv->iio_active) { ++ iio_channel_stop_all_cb(priv->iio_cb); ++ priv->iio_active = false; ++ } ++ + ret = iio_write_channel_attribute(priv->iio_ch, + substream->runtime->rate, 0, + IIO_CHAN_INFO_SAMP_FREQ); + if (ret < 0) { + dev_err(dai->dev, "%s: Failed to set %d sampling rate\n", + __func__, substream->runtime->rate); +- return ret; ++ goto out; + } + + if (!priv->iio_active) { +@@ -92,6 +103,9 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, + __func__, ret); + } + ++out: ++ mutex_unlock(&priv->lock); ++ + return ret; + } + +@@ -298,6 +312,7 @@ static int stm32_adfsdm_probe(struct platform_device *pdev) + + priv->dev = &pdev->dev; + priv->dai_drv = stm32_adfsdm_dai; ++ mutex_init(&priv->lock); + + dev_set_drvdata(&pdev->dev, priv); + +-- +2.20.1 + diff --git a/queue-5.0/asoc-stm32-sai-fix-exposed-capabilities-in-spdif-mod.patch b/queue-5.0/asoc-stm32-sai-fix-exposed-capabilities-in-spdif-mod.patch new file mode 100644 index 00000000000..9d18ef0a98b --- /dev/null +++ b/queue-5.0/asoc-stm32-sai-fix-exposed-capabilities-in-spdif-mod.patch @@ -0,0 +1,40 @@ +From 1a2746ba5a3810fe2a217bd731f107fd33743a09 Mon Sep 17 00:00:00 2001 +From: Olivier Moysan +Date: Thu, 28 Feb 2019 14:19:22 +0100 +Subject: ASoC: stm32: sai: fix exposed capabilities in spdif mode + +[ Upstream commit b8468192971807c43a80d6e2c41f83141cb7b211 ] + +Change capabilities exposed in SAI S/PDIF mode, to match +actually supported formats. +In S/PDIF mode only 32 bits stereo is supported. + +Signed-off-by: Olivier Moysan +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/stm/stm32_sai_sub.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c +index aaacec5b442df..1653cea936cbd 100644 +--- a/sound/soc/stm/stm32_sai_sub.c ++++ b/sound/soc/stm/stm32_sai_sub.c +@@ -682,6 +682,14 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream, + + sai->substream = substream; + ++ if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) { ++ snd_pcm_hw_constraint_mask64(substream->runtime, ++ SNDRV_PCM_HW_PARAM_FORMAT, ++ SNDRV_PCM_FMTBIT_S32_LE); ++ snd_pcm_hw_constraint_single(substream->runtime, ++ SNDRV_PCM_HW_PARAM_CHANNELS, 2); ++ } ++ + ret = clk_prepare_enable(sai->sai_ck); + if (ret < 0) { + dev_err(cpu_dai->dev, "Failed to enable clock: %d\n", ret); +-- +2.20.1 + diff --git a/queue-5.0/asoc-stm32-sai-fix-iec958-controls-indexation.patch b/queue-5.0/asoc-stm32-sai-fix-iec958-controls-indexation.patch new file mode 100644 index 00000000000..ad2b971afcb --- /dev/null +++ b/queue-5.0/asoc-stm32-sai-fix-iec958-controls-indexation.patch @@ -0,0 +1,48 @@ +From dbf133724b3a1cd878dbb1bffdfa2d05eef2d7e9 Mon Sep 17 00:00:00 2001 +From: Olivier Moysan +Date: Thu, 28 Feb 2019 14:19:21 +0100 +Subject: ASoC: stm32: sai: fix iec958 controls indexation + +[ Upstream commit 5f8a1000c3e630c3ac06f1d664eeaa755bce8823 ] + +Allow indexation of sai iec958 controls according +to device id. + +Signed-off-by: Olivier Moysan +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/stm/stm32_sai_sub.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c +index 29a131e0569e7..aaacec5b442df 100644 +--- a/sound/soc/stm/stm32_sai_sub.c ++++ b/sound/soc/stm/stm32_sai_sub.c +@@ -100,7 +100,7 @@ + * @slot_mask: rx or tx active slots mask. set at init or at runtime + * @data_size: PCM data width. corresponds to PCM substream width. + * @spdif_frm_cnt: S/PDIF playback frame counter +- * @snd_aes_iec958: iec958 data ++ * @iec958: iec958 data + * @ctrl_lock: control lock + */ + struct stm32_sai_sub_data { +@@ -1070,11 +1070,12 @@ static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd, + struct snd_soc_dai *cpu_dai) + { + struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); ++ struct snd_kcontrol_new knew = iec958_ctls; + + if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) { + dev_dbg(&sai->pdev->dev, "%s: register iec controls", __func__); +- return snd_ctl_add(rtd->pcm->card, +- snd_ctl_new1(&iec958_ctls, sai)); ++ knew.device = rtd->pcm->device; ++ return snd_ctl_add(rtd->pcm->card, snd_ctl_new1(&knew, sai)); + } + + return 0; +-- +2.20.1 + diff --git a/queue-5.0/asoc-stm32-sai-fix-master-clock-management.patch b/queue-5.0/asoc-stm32-sai-fix-master-clock-management.patch new file mode 100644 index 00000000000..8f9e5f2cde0 --- /dev/null +++ b/queue-5.0/asoc-stm32-sai-fix-master-clock-management.patch @@ -0,0 +1,137 @@ +From fc451a2b34464376802a2e2da2caa695e0e21de3 Mon Sep 17 00:00:00 2001 +From: Olivier Moysan +Date: Wed, 10 Apr 2019 10:08:36 +0200 +Subject: ASoC: stm32: sai: fix master clock management + +[ Upstream commit e37c2deafe7058cf7989c4c47bbf1140cc867d89 ] + +When master clock is used, master clock rate is set exclusively. +Parent clocks of master clock cannot be changed after a call to +clk_set_rate_exclusive(). So the parent clock of SAI kernel clock +must be set before. +Ensure also that exclusive rate operations are balanced +in STM32 SAI driver. + +Signed-off-by: Olivier Moysan +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/stm/stm32_sai_sub.c | 64 +++++++++++++++++++++++++---------- + 1 file changed, 47 insertions(+), 17 deletions(-) + +diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c +index bc69e68191ad1..1cf9df4b6f11c 100644 +--- a/sound/soc/stm/stm32_sai_sub.c ++++ b/sound/soc/stm/stm32_sai_sub.c +@@ -70,6 +70,7 @@ + #define SAI_IEC60958_STATUS_BYTES 24 + + #define SAI_MCLK_NAME_LEN 32 ++#define SAI_RATE_11K 11025 + + /** + * struct stm32_sai_sub_data - private data of SAI sub block (block A or B) +@@ -309,6 +310,25 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai, + return ret; + } + ++static int stm32_sai_set_parent_clock(struct stm32_sai_sub_data *sai, ++ unsigned int rate) ++{ ++ struct platform_device *pdev = sai->pdev; ++ struct clk *parent_clk = sai->pdata->clk_x8k; ++ int ret; ++ ++ if (!(rate % SAI_RATE_11K)) ++ parent_clk = sai->pdata->clk_x11k; ++ ++ ret = clk_set_parent(sai->sai_ck, parent_clk); ++ if (ret) ++ dev_err(&pdev->dev, " Error %d setting sai_ck parent clock. %s", ++ ret, ret == -EBUSY ? ++ "Active stream rates conflict\n" : "\n"); ++ ++ return ret; ++} ++ + static long stm32_sai_mclk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) + { +@@ -490,25 +510,29 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai, + struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); + int ret; + +- if (dir == SND_SOC_CLOCK_OUT) { ++ if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) { + ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, + SAI_XCR1_NODIV, + (unsigned int)~SAI_XCR1_NODIV); + if (ret < 0) + return ret; + +- dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq); +- sai->mclk_rate = freq; ++ /* If master clock is used, set parent clock now */ ++ ret = stm32_sai_set_parent_clock(sai, freq); ++ if (ret) ++ return ret; + +- if (sai->sai_mclk) { +- ret = clk_set_rate_exclusive(sai->sai_mclk, +- sai->mclk_rate); +- if (ret) { +- dev_err(cpu_dai->dev, +- "Could not set mclk rate\n"); +- return ret; +- } ++ ret = clk_set_rate_exclusive(sai->sai_mclk, freq); ++ if (ret) { ++ dev_err(cpu_dai->dev, ++ ret == -EBUSY ? ++ "Active streams have incompatible rates" : ++ "Could not set mclk rate\n"); ++ return ret; + } ++ ++ dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq); ++ sai->mclk_rate = freq; + } + + return 0; +@@ -916,11 +940,13 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai, + int cr1, mask, div = 0; + int sai_clk_rate, mclk_ratio, den; + unsigned int rate = params_rate(params); ++ int ret; + +- if (!(rate % 11025)) +- clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k); +- else +- clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k); ++ if (!sai->sai_mclk) { ++ ret = stm32_sai_set_parent_clock(sai, rate); ++ if (ret) ++ return ret; ++ } + sai_clk_rate = clk_get_rate(sai->sai_ck); + + if (STM_SAI_IS_F4(sai->pdata)) { +@@ -1075,9 +1101,13 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream, + regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_NODIV, + SAI_XCR1_NODIV); + +- clk_disable_unprepare(sai->sai_ck); ++ /* Release mclk rate only if rate was actually set */ ++ if (sai->mclk_rate) { ++ clk_rate_exclusive_put(sai->sai_mclk); ++ sai->mclk_rate = 0; ++ } + +- clk_rate_exclusive_put(sai->sai_mclk); ++ clk_disable_unprepare(sai->sai_ck); + + spin_lock_irqsave(&sai->irq_lock, flags); + sai->substream = NULL; +-- +2.20.1 + diff --git a/queue-5.0/asoc-stm32-sai-fix-race-condition-in-irq-handler.patch b/queue-5.0/asoc-stm32-sai-fix-race-condition-in-irq-handler.patch new file mode 100644 index 00000000000..e1072ec837d --- /dev/null +++ b/queue-5.0/asoc-stm32-sai-fix-race-condition-in-irq-handler.patch @@ -0,0 +1,91 @@ +From 6b3ff4b0b98b707f8ff1fa786fab3e82fa020f99 Mon Sep 17 00:00:00 2001 +From: Olivier Moysan +Date: Thu, 28 Feb 2019 14:19:23 +0100 +Subject: ASoC: stm32: sai: fix race condition in irq handler + +[ Upstream commit 26f98e82dd49b7c3cc5ef0edd882aa732a62b672 ] + +When snd_pcm_stop_xrun() is called in interrupt routine, +substream context may have already been released. +Add protection on substream context. + +Signed-off-by: Olivier Moysan +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/stm/stm32_sai_sub.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c +index 1653cea936cbd..bc69e68191ad1 100644 +--- a/sound/soc/stm/stm32_sai_sub.c ++++ b/sound/soc/stm/stm32_sai_sub.c +@@ -102,6 +102,7 @@ + * @spdif_frm_cnt: S/PDIF playback frame counter + * @iec958: iec958 data + * @ctrl_lock: control lock ++ * @irq_lock: prevent race condition with IRQ + */ + struct stm32_sai_sub_data { + struct platform_device *pdev; +@@ -133,6 +134,7 @@ struct stm32_sai_sub_data { + unsigned int spdif_frm_cnt; + struct snd_aes_iec958 iec958; + struct mutex ctrl_lock; /* protect resources accessed by controls */ ++ spinlock_t irq_lock; /* used to prevent race condition with IRQ */ + }; + + enum stm32_sai_fifo_th { +@@ -474,8 +476,10 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid) + status = SNDRV_PCM_STATE_XRUN; + } + +- if (status != SNDRV_PCM_STATE_RUNNING) ++ spin_lock(&sai->irq_lock); ++ if (status != SNDRV_PCM_STATE_RUNNING && sai->substream) + snd_pcm_stop_xrun(sai->substream); ++ spin_unlock(&sai->irq_lock); + + return IRQ_HANDLED; + } +@@ -679,8 +683,11 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream, + { + struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); + int imr, cr2, ret; ++ unsigned long flags; + ++ spin_lock_irqsave(&sai->irq_lock, flags); + sai->substream = substream; ++ spin_unlock_irqrestore(&sai->irq_lock, flags); + + if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) { + snd_pcm_hw_constraint_mask64(substream->runtime, +@@ -1061,6 +1068,7 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) + { + struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); ++ unsigned long flags; + + regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); + +@@ -1071,7 +1079,9 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream, + + clk_rate_exclusive_put(sai->sai_mclk); + ++ spin_lock_irqsave(&sai->irq_lock, flags); + sai->substream = NULL; ++ spin_unlock_irqrestore(&sai->irq_lock, flags); + } + + static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd, +@@ -1435,6 +1445,7 @@ static int stm32_sai_sub_probe(struct platform_device *pdev) + + sai->pdev = pdev; + mutex_init(&sai->ctrl_lock); ++ spin_lock_init(&sai->irq_lock); + platform_set_drvdata(pdev, sai); + + sai->pdata = dev_get_drvdata(pdev->dev.parent); +-- +2.20.1 + diff --git a/queue-5.0/asoc-tlv320aic32x4-fix-common-pins.patch b/queue-5.0/asoc-tlv320aic32x4-fix-common-pins.patch new file mode 100644 index 00000000000..0da95e8747d --- /dev/null +++ b/queue-5.0/asoc-tlv320aic32x4-fix-common-pins.patch @@ -0,0 +1,33 @@ +From dd031078fd83def8031e9dac84aae1b81644c5ef Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Sat, 30 Mar 2019 09:02:02 -0700 +Subject: ASoC: tlv320aic32x4: Fix Common Pins + +[ Upstream commit c63adb28f6d913310430f14c69f0a2ea55eed0cc ] + +The common pins were mistakenly not added to the DAPM graph. +Adding these pins will allow valid graphs to be created. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tlv320aic32x4.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c +index f03195d2ab2ea..45d9f4a090441 100644 +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -462,6 +462,8 @@ static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("IN2_R"), + SND_SOC_DAPM_INPUT("IN3_L"), + SND_SOC_DAPM_INPUT("IN3_R"), ++ SND_SOC_DAPM_INPUT("CM_L"), ++ SND_SOC_DAPM_INPUT("CM_R"), + }; + + static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = { +-- +2.20.1 + diff --git a/queue-5.0/asoc-tlv320aic3x-fix-reset-gpio-reference-counting.patch b/queue-5.0/asoc-tlv320aic3x-fix-reset-gpio-reference-counting.patch new file mode 100644 index 00000000000..eef8b76a4e6 --- /dev/null +++ b/queue-5.0/asoc-tlv320aic3x-fix-reset-gpio-reference-counting.patch @@ -0,0 +1,68 @@ +From 60ec47a7afb1754955c7116c0adf93691b1e8edd Mon Sep 17 00:00:00 2001 +From: Philipp Puschmann +Date: Wed, 27 Feb 2019 16:17:33 +0100 +Subject: ASoC: tlv320aic3x: fix reset gpio reference counting + +[ Upstream commit 82ad759143ed77673db0d93d53c1cde7b99917ee ] + +This patch fixes a bug that prevents freeing the reset gpio on unloading +the module. + +aic3x_i2c_probe is called when loading the module and it calls list_add +with a probably uninitialized list entry aic3x->list (next = prev = NULL)). +So even if list_del is called it does nothing and in the end the gpio_reset +is not freed. Then a repeated module probing fails silently because +gpio_request fails. + +When moving INIT_LIST_HEAD to aic3x_i2c_probe we also have to move +list_del to aic3x_i2c_remove because aic3x_remove may be called +multiple times without aic3x_i2c_remove being called which leads to +a NULL pointer dereference. + +Signed-off-by: Philipp Puschmann +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tlv320aic3x.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c +index 6aa0edf8c5ef9..cea3ebecdb12b 100644 +--- a/sound/soc/codecs/tlv320aic3x.c ++++ b/sound/soc/codecs/tlv320aic3x.c +@@ -1609,7 +1609,6 @@ static int aic3x_probe(struct snd_soc_component *component) + struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component); + int ret, i; + +- INIT_LIST_HEAD(&aic3x->list); + aic3x->component = component; + + for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) { +@@ -1692,7 +1691,6 @@ static void aic3x_remove(struct snd_soc_component *component) + struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component); + int i; + +- list_del(&aic3x->list); + for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) + regulator_unregister_notifier(aic3x->supplies[i].consumer, + &aic3x->disable_nb[i].nb); +@@ -1890,6 +1888,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, + if (ret != 0) + goto err_gpio; + ++ INIT_LIST_HEAD(&aic3x->list); + list_add(&aic3x->list, &reset_list); + + return 0; +@@ -1906,6 +1905,8 @@ static int aic3x_i2c_remove(struct i2c_client *client) + { + struct aic3x_priv *aic3x = i2c_get_clientdata(client); + ++ list_del(&aic3x->list); ++ + if (gpio_is_valid(aic3x->gpio_reset) && + !aic3x_is_shared_reset(aic3x)) { + gpio_set_value(aic3x->gpio_reset, 0); +-- +2.20.1 + diff --git a/queue-5.0/asoc-wm_adsp-add-locking-to-wm_adsp2_bus_error.patch b/queue-5.0/asoc-wm_adsp-add-locking-to-wm_adsp2_bus_error.patch new file mode 100644 index 00000000000..7f7eeed006a --- /dev/null +++ b/queue-5.0/asoc-wm_adsp-add-locking-to-wm_adsp2_bus_error.patch @@ -0,0 +1,67 @@ +From 18e282d466b528879decf355746d3e410a06b59b Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Tue, 19 Mar 2019 11:52:06 +0000 +Subject: ASoC: wm_adsp: Add locking to wm_adsp2_bus_error + +[ Upstream commit a2225a6d155fcb247fe4c6d87f7c91807462966d ] + +Best to lock across handling the bus error to ensure the DSP doesn't +change power state as we are reading the status registers. + +Signed-off-by: Charles Keepax +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/wm_adsp.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 0600e4404f908..eb5b1be77c479 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -3821,11 +3821,13 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) + struct regmap *regmap = dsp->regmap; + int ret = 0; + ++ mutex_lock(&dsp->pwr_lock); ++ + ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); + if (ret) { + adsp_err(dsp, + "Failed to read Region Lock Ctrl register: %d\n", ret); +- return IRQ_HANDLED; ++ goto error; + } + + if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { +@@ -3844,7 +3846,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) + adsp_err(dsp, + "Failed to read Bus Err Addr register: %d\n", + ret); +- return IRQ_HANDLED; ++ goto error; + } + + adsp_err(dsp, "bus error address = 0x%x\n", +@@ -3857,7 +3859,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) + adsp_err(dsp, + "Failed to read Pmem Xmem Err Addr register: %d\n", + ret); +- return IRQ_HANDLED; ++ goto error; + } + + adsp_err(dsp, "xmem error address = 0x%x\n", +@@ -3870,6 +3872,9 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) + regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, + ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); + ++error: ++ mutex_unlock(&dsp->pwr_lock); ++ + return IRQ_HANDLED; + } + EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); +-- +2.20.1 + diff --git a/queue-5.0/blk-mq-introduce-blk_mq_complete_request_sync.patch b/queue-5.0/blk-mq-introduce-blk_mq_complete_request_sync.patch new file mode 100644 index 00000000000..4d89e936504 --- /dev/null +++ b/queue-5.0/blk-mq-introduce-blk_mq_complete_request_sync.patch @@ -0,0 +1,73 @@ +From 34c778d6616e79adc2c63964202ee38262a4a03a Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Tue, 9 Apr 2019 06:31:21 +0800 +Subject: blk-mq: introduce blk_mq_complete_request_sync() + +[ Upstream commit 1b8f21b74c3c9c82fce5a751d7aefb7cc0b8d33d ] + +In NVMe's error handler, follows the typical steps of tearing down +hardware for recovering controller: + +1) stop blk_mq hw queues +2) stop the real hw queues +3) cancel in-flight requests via + blk_mq_tagset_busy_iter(tags, cancel_request, ...) +cancel_request(): + mark the request as abort + blk_mq_complete_request(req); +4) destroy real hw queues + +However, there may be race between #3 and #4, because blk_mq_complete_request() +may run q->mq_ops->complete(rq) remotelly and asynchronously, and +->complete(rq) may be run after #4. + +This patch introduces blk_mq_complete_request_sync() for fixing the +above race. + +Cc: Sagi Grimberg +Cc: Bart Van Assche +Cc: James Smart +Cc: linux-nvme@lists.infradead.org +Reviewed-by: Keith Busch +Reviewed-by: Christoph Hellwig +Signed-off-by: Ming Lei +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-mq.c | 7 +++++++ + include/linux/blk-mq.h | 1 + + 2 files changed, 8 insertions(+) + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 5a2585d69c817..6930c82ab75fc 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -657,6 +657,13 @@ bool blk_mq_complete_request(struct request *rq) + } + EXPORT_SYMBOL(blk_mq_complete_request); + ++void blk_mq_complete_request_sync(struct request *rq) ++{ ++ WRITE_ONCE(rq->state, MQ_RQ_COMPLETE); ++ rq->q->mq_ops->complete(rq); ++} ++EXPORT_SYMBOL_GPL(blk_mq_complete_request_sync); ++ + int blk_mq_request_started(struct request *rq) + { + return blk_mq_rq_state(rq) != MQ_RQ_IDLE; +diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h +index 0e030f5f76b66..7e092bdac27f6 100644 +--- a/include/linux/blk-mq.h ++++ b/include/linux/blk-mq.h +@@ -306,6 +306,7 @@ void blk_mq_add_to_requeue_list(struct request *rq, bool at_head, + void blk_mq_kick_requeue_list(struct request_queue *q); + void blk_mq_delay_kick_requeue_list(struct request_queue *q, unsigned long msecs); + bool blk_mq_complete_request(struct request *rq); ++void blk_mq_complete_request_sync(struct request *rq); + bool blk_mq_bio_list_merge(struct request_queue *q, struct list_head *list, + struct bio *bio); + bool blk_mq_queue_stopped(struct request_queue *q); +-- +2.20.1 + diff --git a/queue-5.0/clk-meson-gxbb-round-the-vdec-dividers-to-closest.patch b/queue-5.0/clk-meson-gxbb-round-the-vdec-dividers-to-closest.patch new file mode 100644 index 00000000000..fc76268fbee --- /dev/null +++ b/queue-5.0/clk-meson-gxbb-round-the-vdec-dividers-to-closest.patch @@ -0,0 +1,46 @@ +From cd762226fd2de2586fe246e81c01a3dd1146abfd Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Tue, 19 Mar 2019 11:25:37 +0100 +Subject: clk: meson-gxbb: round the vdec dividers to closest + +[ Upstream commit 9b70c697e87286ade406e6a02091757307dd4b7c ] + +We want the video decoder clocks to always round to closest. While the +muxes are already using CLK_MUX_ROUND_CLOSEST, the corresponding +CLK_DIVIDER_ROUND_CLOSEST was forgotten for the dividers. + +Fix this by adding the flag to the two vdec dividers. + +Fixes: a565242eb9fc ("clk: meson: gxbb: add the video decoder clocks") +Signed-off-by: Maxime Jourdan +Acked-by: Neil Armstrong +Signed-off-by: Neil Armstrong +Link: https://lkml.kernel.org/r/20190319102537.2043-1-mjourdan@baylibre.com +Signed-off-by: Sasha Levin +--- + drivers/clk/meson/gxbb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c +index 65f2599e52434..08824b2cd1428 100644 +--- a/drivers/clk/meson/gxbb.c ++++ b/drivers/clk/meson/gxbb.c +@@ -2213,6 +2213,7 @@ static struct clk_regmap gxbb_vdec_1_div = { + .offset = HHI_VDEC_CLK_CNTL, + .shift = 0, + .width = 7, ++ .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_1_div", +@@ -2258,6 +2259,7 @@ static struct clk_regmap gxbb_vdec_hevc_div = { + .offset = HHI_VDEC2_CLK_CNTL, + .shift = 16, + .width = 7, ++ .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevc_div", +-- +2.20.1 + diff --git a/queue-5.0/drm-amd-display-fix-cursor-black-issue.patch b/queue-5.0/drm-amd-display-fix-cursor-black-issue.patch new file mode 100644 index 00000000000..73f45d2aa1b --- /dev/null +++ b/queue-5.0/drm-amd-display-fix-cursor-black-issue.patch @@ -0,0 +1,40 @@ +From 2d0f06f33938395f6eb92bc74097838998676e46 Mon Sep 17 00:00:00 2001 +From: tiancyin +Date: Mon, 1 Apr 2019 10:15:31 +0800 +Subject: drm/amd/display: fix cursor black issue + +[ Upstream commit c1cefe115d1cdc460014483319d440b2f0d07c68 ] + +[Why] +the member sdr_white_level of struct dc_cursor_attributes was not +initialized, then the random value result that +dcn10_set_cursor_sdr_white_level() set error hw_scale value 0x20D9(normal +value is 0x3c00), this cause the black cursor issue. + +[how] +just initilize the obj of struct dc_cursor_attributes to zero to avoid +the random value. + +Reviewed-by: Nicholas Kazlauskas +Signed-off-by: Tianci Yin +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 83c8a0407537b..84ee777869441 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -4455,6 +4455,7 @@ static void handle_cursor_update(struct drm_plane *plane, + amdgpu_crtc->cursor_width = plane->state->crtc_w; + amdgpu_crtc->cursor_height = plane->state->crtc_h; + ++ memset(&attributes, 0, sizeof(attributes)); + attributes.address.high_part = upper_32_bits(address); + attributes.address.low_part = lower_32_bits(address); + attributes.width = plane->state->crtc_w; +-- +2.20.1 + diff --git a/queue-5.0/drm-amdgpu-adjust-ib-test-timeout-for-xgmi-configura.patch b/queue-5.0/drm-amdgpu-adjust-ib-test-timeout-for-xgmi-configura.patch new file mode 100644 index 00000000000..64b453f0cae --- /dev/null +++ b/queue-5.0/drm-amdgpu-adjust-ib-test-timeout-for-xgmi-configura.patch @@ -0,0 +1,44 @@ +From 43451ac8372284c868375c306e4ac43430ec53b2 Mon Sep 17 00:00:00 2001 +From: shaoyunl +Date: Mon, 1 Apr 2019 16:09:34 -0400 +Subject: drm/amdgpu: Adjust IB test timeout for XGMI configuration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit d4162c61e253177936fcfe6c29f7b224d9a1efb8 ] + +On XGMI configuration the ib test may take longer to finish + +Signed-off-by: shaoyunl +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +index c48207b377bc5..b82c5fca217b3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +@@ -35,6 +35,7 @@ + #include "amdgpu_trace.h" + + #define AMDGPU_IB_TEST_TIMEOUT msecs_to_jiffies(1000) ++#define AMDGPU_IB_TEST_GFX_XGMI_TIMEOUT msecs_to_jiffies(2000) + + /* + * IB +@@ -344,6 +345,8 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev) + * cost waiting for it coming back under RUNTIME only + */ + tmo_gfx = 8 * AMDGPU_IB_TEST_TIMEOUT; ++ } else if (adev->gmc.xgmi.hive_id) { ++ tmo_gfx = AMDGPU_IB_TEST_GFX_XGMI_TIMEOUT; + } + + for (i = 0; i < adev->num_rings; ++i) { +-- +2.20.1 + diff --git a/queue-5.0/drm-amdgpu-amdgpu_device_recover_vram-always-failed-.patch b/queue-5.0/drm-amdgpu-amdgpu_device_recover_vram-always-failed-.patch new file mode 100644 index 00000000000..8fa884b5773 --- /dev/null +++ b/queue-5.0/drm-amdgpu-amdgpu_device_recover_vram-always-failed-.patch @@ -0,0 +1,62 @@ +From 1eeea9f7709cb7ed1ecc2cb75f01b0ae0865d188 Mon Sep 17 00:00:00 2001 +From: wentalou +Date: Tue, 2 Apr 2019 17:13:05 +0800 +Subject: drm/amdgpu: amdgpu_device_recover_vram always failed if only one node + in shadow_list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit 1712fb1a2f6829150032ac76eb0e39b82a549cfb ] + +amdgpu_bo_restore_shadow would assign zero to r if succeeded. +r would remain zero if there is only one node in shadow_list. +current code would always return failure when r <= 0. +restart the timeout for each wait was a rather problematic bug as well. +The value of tmo SHOULD be changed, otherwise we wait tmo jiffies on each loop. + +Signed-off-by: Wentao Lou +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 7ff3a28fc9038..d55dd570a7023 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -3158,11 +3158,16 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) + break; + + if (fence) { +- r = dma_fence_wait_timeout(fence, false, tmo); ++ tmo = dma_fence_wait_timeout(fence, false, tmo); + dma_fence_put(fence); + fence = next; +- if (r <= 0) ++ if (tmo == 0) { ++ r = -ETIMEDOUT; + break; ++ } else if (tmo < 0) { ++ r = tmo; ++ break; ++ } + } else { + fence = next; + } +@@ -3173,8 +3178,8 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) + tmo = dma_fence_wait_timeout(fence, false, tmo); + dma_fence_put(fence); + +- if (r <= 0 || tmo <= 0) { +- DRM_ERROR("recover vram bo from shadow failed\n"); ++ if (r < 0 || tmo <= 0) { ++ DRM_ERROR("recover vram bo from shadow failed, r is %ld, tmo is %ld\n", r, tmo); + return -EIO; + } + +-- +2.20.1 + diff --git a/queue-5.0/drm-amdkfd-add-picasso-pci-id.patch b/queue-5.0/drm-amdkfd-add-picasso-pci-id.patch new file mode 100644 index 00000000000..f11bca8d24b --- /dev/null +++ b/queue-5.0/drm-amdkfd-add-picasso-pci-id.patch @@ -0,0 +1,31 @@ +From 19cae4b43157e925e4020e1cff4f0f736ded1cba Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 3 Apr 2019 12:30:32 -0500 +Subject: drm/amdkfd: Add picasso pci id + +[ Upstream commit e7ad88553aa1d48e950ca9a4934d246c1bee4be4 ] + +Picasso is a new raven variant. + +Reviewed-by: Kent Russell +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_device.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c +index 8be9677c0c07d..cf9a49f49d3a4 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c +@@ -320,6 +320,7 @@ static const struct kfd_deviceid supported_devices[] = { + { 0x9876, &carrizo_device_info }, /* Carrizo */ + { 0x9877, &carrizo_device_info }, /* Carrizo */ + { 0x15DD, &raven_device_info }, /* Raven */ ++ { 0x15D8, &raven_device_info }, /* Raven */ + #endif + { 0x67A0, &hawaii_device_info }, /* Hawaii */ + { 0x67A1, &hawaii_device_info }, /* Hawaii */ +-- +2.20.1 + diff --git a/queue-5.0/drm-mediatek-fix-an-error-code-in-mtk_hdmi_dt_parse_.patch b/queue-5.0/drm-mediatek-fix-an-error-code-in-mtk_hdmi_dt_parse_.patch new file mode 100644 index 00000000000..b8c14d0f8c7 --- /dev/null +++ b/queue-5.0/drm-mediatek-fix-an-error-code-in-mtk_hdmi_dt_parse_.patch @@ -0,0 +1,33 @@ +From 432271ffc390ae610e302a232d42f2ceffa52009 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 28 Mar 2019 17:31:30 +0300 +Subject: drm/mediatek: Fix an error code in mtk_hdmi_dt_parse_pdata() + +[ Upstream commit 2d85978341e6a32e7443d9f28639da254d53f400 ] + +We don't want to overwrite "ret", it already holds the correct error +code. The "regmap" variable might be a valid pointer as this point. + +Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support") +Signed-off-by: Dan Carpenter +Signed-off-by: CK Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_hdmi.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c +index 862f3ec221318..c910850d20770 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c +@@ -1479,7 +1479,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, + if (IS_ERR(regmap)) + ret = PTR_ERR(regmap); + if (ret) { +- ret = PTR_ERR(regmap); + dev_err(dev, + "Failed to get system configuration registers: %d\n", + ret); +-- +2.20.1 + diff --git a/queue-5.0/drm-mediatek-fix-possible-object-reference-leak.patch b/queue-5.0/drm-mediatek-fix-possible-object-reference-leak.patch new file mode 100644 index 00000000000..d65849fa98d --- /dev/null +++ b/queue-5.0/drm-mediatek-fix-possible-object-reference-leak.patch @@ -0,0 +1,46 @@ +From a2aff2d1ebde7d8deeab925c79e903339b381c81 Mon Sep 17 00:00:00 2001 +From: Wen Yang +Date: Thu, 4 Apr 2019 00:04:09 +0800 +Subject: drm/mediatek: fix possible object reference leak + +[ Upstream commit 2ae2c3316fb77dcf64275d011596b60104c45426 ] + +The call to of_parse_phandle returns a node pointer with refcount +incremented thus it must be explicitly decremented after the last +usage. + +Detected by coccinelle with the following warnings: +drivers/gpu/drm/mediatek/mtk_hdmi.c:1521:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 1509, but without a corresponding object release within this function. +drivers/gpu/drm/mediatek/mtk_hdmi.c:1524:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 1509, but without a corresponding object release within this function. + +Signed-off-by: Wen Yang +Cc: CK Hu +Cc: Philipp Zabel +Cc: David Airlie +Cc: Daniel Vetter +Cc: Matthias Brugger +Cc: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-mediatek@lists.infradead.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: CK Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_hdmi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c +index c910850d20770..a687fe3e1d6c5 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c +@@ -1514,6 +1514,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, + of_node_put(remote); + + hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np); ++ of_node_put(i2c_np); + if (!hdmi->ddc_adpt) { + dev_err(dev, "Failed to get ddc i2c adapter by node\n"); + return -EINVAL; +-- +2.20.1 + diff --git a/queue-5.0/drm-mediatek-fix-the-rate-and-divder-of-hdmi-phy-for.patch b/queue-5.0/drm-mediatek-fix-the-rate-and-divder-of-hdmi-phy-for.patch new file mode 100644 index 00000000000..9258b5a9156 --- /dev/null +++ b/queue-5.0/drm-mediatek-fix-the-rate-and-divder-of-hdmi-phy-for.patch @@ -0,0 +1,36 @@ +From 46a5679dcf42637194e5a23178e1966a8e4ba2c6 Mon Sep 17 00:00:00 2001 +From: Wangyan Wang +Date: Tue, 9 Apr 2019 14:53:04 +0800 +Subject: drm/mediatek: fix the rate and divder of hdmi phy for MT2701 + +[ Upstream commit 0c24613cda163dedfa229afc8eff6072e57fac8d ] + +Due to a clerical error,there is one zero less for 12800000. +Fix it for 128000000 +Fixes: 0fc721b2968e ("drm/mediatek: add hdmi driver for MT2701 and MT7623") + +Signed-off-by: Wangyan Wang +Signed-off-by: CK Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +index fcc42dc6ea7fb..0746fc8877069 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +@@ -116,8 +116,8 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + + if (rate <= 64000000) + pos_div = 3; +- else if (rate <= 12800000) +- pos_div = 1; ++ else if (rate <= 128000000) ++ pos_div = 2; + else + pos_div = 1; + +-- +2.20.1 + diff --git a/queue-5.0/drm-mediatek-make-implementation-of-recalc_rate-for-.patch b/queue-5.0/drm-mediatek-make-implementation-of-recalc_rate-for-.patch new file mode 100644 index 00000000000..02158e676fa --- /dev/null +++ b/queue-5.0/drm-mediatek-make-implementation-of-recalc_rate-for-.patch @@ -0,0 +1,159 @@ +From 17a16007504dea1e8a367c5dbe0a31b85e1fbc4d Mon Sep 17 00:00:00 2001 +From: Wangyan Wang +Date: Tue, 9 Apr 2019 14:53:06 +0800 +Subject: drm/mediatek: make implementation of recalc_rate() for MT2701 hdmi + phy + +[ Upstream commit 321b628e6f5a3af999f75eadd373adbcb8b4cb1f ] + +Recalculate the rate of this clock, by querying hardware to +make implementation of recalc_rate() to match the definition. + +Signed-off-by: Wangyan Wang +Signed-off-by: CK Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 8 ---- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 2 - + .../gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 38 +++++++++++++++++-- + .../gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 8 ++++ + 4 files changed, 42 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +index 4ef9c57ffd44d..efc400ebbb90b 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +@@ -29,14 +29,6 @@ long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, + return rate; + } + +-unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, +- unsigned long parent_rate) +-{ +- struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); +- +- return hdmi_phy->pll_rate; +-} +- + void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, + u32 bits) + { +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +index f39b1fc666129..71430691ffe43 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +@@ -50,8 +50,6 @@ void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, + struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); + long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate); +-unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, +- unsigned long parent_rate); + + extern struct platform_driver mtk_hdmi_phy_driver; + extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; +diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +index 0746fc8877069..feb6a7ed63d16 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +@@ -79,7 +79,6 @@ static int mtk_hdmi_pll_prepare(struct clk_hw *hw) + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); + usleep_range(80, 100); + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); +- mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); +@@ -94,7 +93,6 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); +- mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); + usleep_range(80, 100); + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); +@@ -123,6 +121,7 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK); + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC), + RG_HTPLL_IC_MASK); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR), +@@ -154,6 +153,39 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + ++static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); ++ unsigned long out_rate, val; ++ ++ val = (readl(hdmi_phy->regs + HDMI_CON6) ++ & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV; ++ switch (val) { ++ case 0x00: ++ out_rate = parent_rate; ++ break; ++ case 0x01: ++ out_rate = parent_rate / 2; ++ break; ++ default: ++ out_rate = parent_rate / 4; ++ break; ++ } ++ ++ val = (readl(hdmi_phy->regs + HDMI_CON6) ++ & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV; ++ out_rate *= (val + 1) * 2; ++ val = (readl(hdmi_phy->regs + HDMI_CON2) ++ & RG_HDMITX_TX_POSDIV_MASK); ++ out_rate >>= (val >> RG_HDMITX_TX_POSDIV); ++ ++ if (readl(hdmi_phy->regs + HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV) ++ out_rate /= 5; ++ ++ return out_rate; ++} ++ + static const struct clk_ops mtk_hdmi_phy_pll_ops = { + .prepare = mtk_hdmi_pll_prepare, + .unprepare = mtk_hdmi_pll_unprepare, +@@ -174,7 +206,6 @@ static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy) + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); + usleep_range(80, 100); + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); +- mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); +@@ -186,7 +217,6 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); +- mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); + usleep_range(80, 100); + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); +diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +index ed5916b276584..83662a2084916 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +@@ -285,6 +285,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + ++static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); ++ ++ return hdmi_phy->pll_rate; ++} ++ + static const struct clk_ops mtk_hdmi_phy_pll_ops = { + .prepare = mtk_hdmi_pll_prepare, + .unprepare = mtk_hdmi_pll_unprepare, +-- +2.20.1 + diff --git a/queue-5.0/drm-mediatek-no-change-parent-rate-in-round_rate-for.patch b/queue-5.0/drm-mediatek-no-change-parent-rate-in-round_rate-for.patch new file mode 100644 index 00000000000..db82abad12a --- /dev/null +++ b/queue-5.0/drm-mediatek-no-change-parent-rate-in-round_rate-for.patch @@ -0,0 +1,107 @@ +From 10d8c993525beb0ff045635d3ef2de22da93f8b3 Mon Sep 17 00:00:00 2001 +From: Wangyan Wang +Date: Tue, 9 Apr 2019 14:53:07 +0800 +Subject: drm/mediatek: no change parent rate in round_rate() for MT2701 hdmi + phy + +[ Upstream commit 9ee76098a1b8ae21cccac641b735ee4d3a77bccf ] + +This is the third step to make MT2701 HDMI stable. +We should not change the rate of parent for hdmi phy when +doing round_rate for this clock. The parent clock of hdmi +phy must be the same as it. We change it when doing set_rate +only. + +Signed-off-by: Wangyan Wang +Signed-off-by: CK Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 14 -------------- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 2 -- + drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 6 ++++++ + drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 14 ++++++++++++++ + 4 files changed, 20 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +index 08b029772c5a5..5223498502c49 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +@@ -15,20 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = { + .owner = THIS_MODULE, + }; + +-long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, +- unsigned long *parent_rate) +-{ +- struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); +- +- hdmi_phy->pll_rate = rate; +- if (rate <= 74250000) +- *parent_rate = rate; +- else +- *parent_rate = rate / 2; +- +- return rate; +-} +- + void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, + u32 bits) + { +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +index d28b8d5ed2b44..2d8b3182470dc 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +@@ -49,8 +49,6 @@ void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, + void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, + u32 val, u32 mask); + struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); +-long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, +- unsigned long *parent_rate); + + extern struct platform_driver mtk_hdmi_phy_driver; + extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; +diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +index 31f3175f032bc..d3cc4022e9884 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +@@ -106,6 +106,12 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) + usleep_range(80, 100); + } + ++static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ return rate; ++} ++ + static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) + { +diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +index 37f9503d76433..47f8a29516822 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +@@ -199,6 +199,20 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) + usleep_range(100, 150); + } + ++static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); ++ ++ hdmi_phy->pll_rate = rate; ++ if (rate <= 74250000) ++ *parent_rate = rate; ++ else ++ *parent_rate = rate / 2; ++ ++ return rate; ++} ++ + static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) + { +-- +2.20.1 + diff --git a/queue-5.0/drm-mediatek-remove-flag-clk_set_rate_parent-for-mt2.patch b/queue-5.0/drm-mediatek-remove-flag-clk_set_rate_parent-for-mt2.patch new file mode 100644 index 00000000000..db1599465b4 --- /dev/null +++ b/queue-5.0/drm-mediatek-remove-flag-clk_set_rate_parent-for-mt2.patch @@ -0,0 +1,101 @@ +From b380dc0c9465a4366d94a3b0c55bfabd26fce0f3 Mon Sep 17 00:00:00 2001 +From: Wangyan Wang +Date: Tue, 9 Apr 2019 14:53:03 +0800 +Subject: drm/mediatek: remove flag CLK_SET_RATE_PARENT for MT2701 hdmi phy + +[ Upstream commit 827abdd024207146822f66ba3ba74867135866b9 ] + +This is the first step to make MT2701 hdmi stable. +The parent rate of hdmi phy had set by DPI driver. +We should not set or change the parent rate of MT2701 hdmi phy, +as a result we should remove the flags of "CLK_SET_RATE_PARENT" +from the clock of MT2701 hdmi phy. + +Signed-off-by: Wangyan Wang +Signed-off-by: CK Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 13 +++++-------- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 1 + + drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 1 + + drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 1 + + 4 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +index efc400ebbb90b..08b029772c5a5 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +@@ -102,13 +102,11 @@ mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy) + return NULL; + } + +-static void mtk_hdmi_phy_clk_get_ops(struct mtk_hdmi_phy *hdmi_phy, +- const struct clk_ops **ops) ++static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy, ++ struct clk_init_data *clk_init) + { +- if (hdmi_phy && hdmi_phy->conf && hdmi_phy->conf->hdmi_phy_clk_ops) +- *ops = hdmi_phy->conf->hdmi_phy_clk_ops; +- else +- dev_err(hdmi_phy->dev, "Failed to get clk ops of phy\n"); ++ clk_init->flags = hdmi_phy->conf->flags; ++ clk_init->ops = hdmi_phy->conf->hdmi_phy_clk_ops; + } + + static int mtk_hdmi_phy_probe(struct platform_device *pdev) +@@ -121,7 +119,6 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) + struct clk_init_data clk_init = { + .num_parents = 1, + .parent_names = (const char * const *)&ref_clk_name, +- .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, + }; + + struct phy *phy; +@@ -159,7 +156,7 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) + hdmi_phy->dev = dev; + hdmi_phy->conf = + (struct mtk_hdmi_phy_conf *)of_device_get_match_data(dev); +- mtk_hdmi_phy_clk_get_ops(hdmi_phy, &clk_init.ops); ++ mtk_hdmi_phy_clk_get_data(hdmi_phy, &clk_init); + hdmi_phy->pll_hw.init = &clk_init; + hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw); + if (IS_ERR(hdmi_phy->pll)) { +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +index 71430691ffe43..d28b8d5ed2b44 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +@@ -21,6 +21,7 @@ struct mtk_hdmi_phy; + + struct mtk_hdmi_phy_conf { + bool tz_disabled; ++ unsigned long flags; + const struct clk_ops *hdmi_phy_clk_ops; + void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); + void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); +diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +index feb6a7ed63d16..31f3175f032bc 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +@@ -232,6 +232,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) + + struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { + .tz_disabled = true, ++ .flags = CLK_SET_RATE_GATE, + .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, + .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, + .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, +diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +index 83662a2084916..37f9503d76433 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +@@ -317,6 +317,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) + } + + struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = { ++ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, + .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, + .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, + .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, +-- +2.20.1 + diff --git a/queue-5.0/drm-mediatek-using-new-factor-for-tvdpll-for-mt2701-.patch b/queue-5.0/drm-mediatek-using-new-factor-for-tvdpll-for-mt2701-.patch new file mode 100644 index 00000000000..72dfe35028f --- /dev/null +++ b/queue-5.0/drm-mediatek-using-new-factor-for-tvdpll-for-mt2701-.patch @@ -0,0 +1,43 @@ +From 37939ba19c889c6ff5a4de9ed006ea4642561f1b Mon Sep 17 00:00:00 2001 +From: Wangyan Wang +Date: Tue, 9 Apr 2019 14:53:05 +0800 +Subject: drm/mediatek: using new factor for tvdpll for MT2701 hdmi phy + +[ Upstream commit 8eeb3946feeb00486ac0909e2309da87db8988a5 ] + +This is the second step to make MT2701 HDMI stable. +The factor depends on the divider of DPI in MT2701, therefore, +we should fix this factor to the right and new one. +Test: search ok + +Signed-off-by: Wangyan Wang +Signed-off-by: CK Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 62a9d47df9487..9160c55769f8d 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -662,13 +662,11 @@ static unsigned int mt8173_calculate_factor(int clock) + static unsigned int mt2701_calculate_factor(int clock) + { + if (clock <= 64000) +- return 16; +- else if (clock <= 128000) +- return 8; +- else if (clock <= 256000) + return 4; +- else ++ else if (clock <= 128000) + return 2; ++ else ++ return 1; + } + + static const struct mtk_dpi_conf mt8173_conf = { +-- +2.20.1 + diff --git a/queue-5.0/drm-omap-hdmi4_cec-fix-cec-clock-handling-for-pm.patch b/queue-5.0/drm-omap-hdmi4_cec-fix-cec-clock-handling-for-pm.patch new file mode 100644 index 00000000000..b6314eeb0e2 --- /dev/null +++ b/queue-5.0/drm-omap-hdmi4_cec-fix-cec-clock-handling-for-pm.patch @@ -0,0 +1,101 @@ +From 75492116cb38350e9e3d7ee04907f7367f2b9292 Mon Sep 17 00:00:00 2001 +From: Tony Lindgren +Date: Tue, 26 Mar 2019 08:14:37 -0700 +Subject: drm/omap: hdmi4_cec: Fix CEC clock handling for PM + +[ Upstream commit 36a1da15b5df493241b0011d2185fdd724ac1ed1 ] + +If CONFIG_OMAP4_DSS_HDMI_CEC is enabled in .config, deeper SoC idle +states are blocked because the CEC clock gets always enabled on init. + +Let's fix the issue by moving the CEC clock handling to happen later in +hdmi_cec_adap_enable() as suggested by Hans Verkuil . +This way the CEC clock gets only enabled when needed. This can be tested +by doing cec-ctl --playback to enable the CEC, and doing cec-ctl --clear +to disable it. + +Let's also fix the typo for "divider" in the comments while at it. + +Fixes: 8d7f934df8d8 ("omapdrm: hdmi4_cec: add OMAP4 HDMI CEC support") +Suggested-by: Hans Verkuil +Cc: Hans Verkuil +Cc: Jyri Sarha +Cc: Laurent Pinchart +Signed-off-by: Tony Lindgren +Reviewed-by: Hans Verkuil +Signed-off-by: Tomi Valkeinen +Link: https://patchwork.freedesktop.org/patch/msgid/20190326151438.32414-1-tony@atomide.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 26 ++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +index 340383150fb98..ebf9c96d43eee 100644 +--- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c ++++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +@@ -175,6 +175,7 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) + REG_FLD_MOD(core->base, HDMI_CORE_SYS_INTR_UNMASK4, 0, 3, 3); + hdmi_wp_clear_irqenable(core->wp, HDMI_IRQ_CORE); + hdmi_wp_set_irqstatus(core->wp, HDMI_IRQ_CORE); ++ REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0, 5, 0); + hdmi4_core_disable(core); + return 0; + } +@@ -182,16 +183,24 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) + if (err) + return err; + ++ /* ++ * Initialize CEC clock divider: CEC needs 2MHz clock hence ++ * set the divider to 24 to get 48/24=2MHz clock ++ */ ++ REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0x18, 5, 0); ++ + /* Clear TX FIFO */ + if (!hdmi_cec_clear_tx_fifo(adap)) { + pr_err("cec-%s: could not clear TX FIFO\n", adap->name); +- return -EIO; ++ err = -EIO; ++ goto err_disable_clk; + } + + /* Clear RX FIFO */ + if (!hdmi_cec_clear_rx_fifo(adap)) { + pr_err("cec-%s: could not clear RX FIFO\n", adap->name); +- return -EIO; ++ err = -EIO; ++ goto err_disable_clk; + } + + /* Clear CEC interrupts */ +@@ -236,6 +245,12 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) + hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, temp); + } + return 0; ++ ++err_disable_clk: ++ REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0, 5, 0); ++ hdmi4_core_disable(core); ++ ++ return err; + } + + static int hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) +@@ -333,11 +348,8 @@ int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, + return ret; + core->wp = wp; + +- /* +- * Initialize CEC clock divider: CEC needs 2MHz clock hence +- * set the devider to 24 to get 48/24=2MHz clock +- */ +- REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0x18, 5, 0); ++ /* Disable clock initially, hdmi_cec_adap_enable() manages it */ ++ REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0, 5, 0); + + ret = cec_register_adapter(core->adap, &pdev->dev); + if (ret < 0) { +-- +2.20.1 + diff --git a/queue-5.0/drm-sun4i-tcon-top-fix-null-invalid-pointer-derefere.patch b/queue-5.0/drm-sun4i-tcon-top-fix-null-invalid-pointer-derefere.patch new file mode 100644 index 00000000000..5b827f450f5 --- /dev/null +++ b/queue-5.0/drm-sun4i-tcon-top-fix-null-invalid-pointer-derefere.patch @@ -0,0 +1,72 @@ +From 3fcd9f767a22f2a16a68729e429ef6fc90f1775b Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Sat, 6 Apr 2019 01:30:48 +0200 +Subject: drm/sun4i: tcon top: Fix NULL/invalid pointer dereference in + sun8i_tcon_top_un/bind + +[ Upstream commit 1a07a94b47b1f528f39c3e6187b5eaf02efe44ea ] + +There are two problems here: + +1. Not all clk_data->hws[] need to be initialized, depending on various + configured quirks. This leads to NULL ptr deref in + clk_hw_unregister_gate() in sun8i_tcon_top_unbind() +2. If there is error when registering the clk_data->hws[], + err_unregister_gates error path will try to unregister + IS_ERR()=true (invalid) pointer. + +For problem (1) I have this stack trace: + +Unable to handle kernel NULL pointer dereference at virtual + address 0000000000000008 +Call trace: + clk_hw_unregister+0x8/0x18 + clk_hw_unregister_gate+0x14/0x28 + sun8i_tcon_top_unbind+0x2c/0x60 + component_unbind.isra.4+0x2c/0x50 + component_bind_all+0x1d4/0x230 + sun4i_drv_bind+0xc4/0x1a0 + try_to_bring_up_master+0x164/0x1c0 + __component_add+0xa0/0x168 + component_add+0x10/0x18 + sun8i_dw_hdmi_probe+0x18/0x20 + platform_drv_probe+0x3c/0x70 + really_probe+0xcc/0x278 + driver_probe_device+0x34/0xa8 + +Problem (2) was identified by head scratching. + +Signed-off-by: Ondrej Jirman +Signed-off-by: Maxime Ripard +Link: https://patchwork.freedesktop.org/patch/msgid/20190405233048.3823-1-megous@megous.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c +index fc36e0c10a374..b1e7c76e9c172 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c ++++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c +@@ -227,7 +227,7 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master, + + err_unregister_gates: + for (i = 0; i < CLK_NUM; i++) +- if (clk_data->hws[i]) ++ if (!IS_ERR_OR_NULL(clk_data->hws[i])) + clk_hw_unregister_gate(clk_data->hws[i]); + clk_disable_unprepare(tcon_top->bus); + err_assert_reset: +@@ -245,7 +245,8 @@ static void sun8i_tcon_top_unbind(struct device *dev, struct device *master, + + of_clk_del_provider(dev->of_node); + for (i = 0; i < CLK_NUM; i++) +- clk_hw_unregister_gate(clk_data->hws[i]); ++ if (clk_data->hws[i]) ++ clk_hw_unregister_gate(clk_data->hws[i]); + + clk_disable_unprepare(tcon_top->bus); + reset_control_assert(tcon_top->rst); +-- +2.20.1 + diff --git a/queue-5.0/ib-hfi1-clear-the-iowait-pending-bits-when-qp-is-put.patch b/queue-5.0/ib-hfi1-clear-the-iowait-pending-bits-when-qp-is-put.patch new file mode 100644 index 00000000000..dcedc0115ab --- /dev/null +++ b/queue-5.0/ib-hfi1-clear-the-iowait-pending-bits-when-qp-is-put.patch @@ -0,0 +1,48 @@ +From 0b2831840daeb32bb0c286cc92fbbd1451cebf18 Mon Sep 17 00:00:00 2001 +From: Kaike Wan +Date: Mon, 18 Mar 2019 09:55:29 -0700 +Subject: IB/hfi1: Clear the IOWAIT pending bits when QP is put into error + state + +[ Upstream commit 93b289b9aff66eca7575b09f36f5abbeca8e6167 ] + +When a QP is put into error state, it may be waiting for send engine +resources. In this case, the QP will be removed from the send engine's +waiting list, but its IOWAIT pending bits are not cleared. This will +normally not have any major impact as the QP is being destroyed. However, +the QP still needs to wind down its operations, such as draining the send +queue by scheduling the send engine. Clearing the pending bits will avoid +any potential complications. In addition, if the QP will eventually hang, +clearing the pending bits can help debugging by presenting a consistent +picture if the user dumps the qp_stats. + +This patch clears a QP's IOWAIT_PENDING_IB and IO_PENDING_TID bits in +priv->s_iowait.flags in this case. + +Fixes: 5da0fc9dbf89 ("IB/hfi1: Prepare resource waits for dual leg") +Reviewed-by: Mike Marciniszyn +Reviewed-by: Alex Estrin +Signed-off-by: Kaike Wan +Signed-off-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hfi1/qp.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c +index 5866f358ea044..df8e812804b34 100644 +--- a/drivers/infiniband/hw/hfi1/qp.c ++++ b/drivers/infiniband/hw/hfi1/qp.c +@@ -834,6 +834,8 @@ void notify_error_qp(struct rvt_qp *qp) + if (!list_empty(&priv->s_iowait.list) && + !(qp->s_flags & RVT_S_BUSY)) { + qp->s_flags &= ~HFI1_S_ANY_WAIT_IO; ++ iowait_clear_flag(&priv->s_iowait, IOWAIT_PENDING_IB); ++ iowait_clear_flag(&priv->s_iowait, IOWAIT_PENDING_TID); + list_del_init(&priv->s_iowait.list); + priv->s_iowait.lock = NULL; + rvt_put_qp(qp); +-- +2.20.1 + diff --git a/queue-5.0/ib-hfi1-eliminate-opcode-tests-on-mr-deref.patch b/queue-5.0/ib-hfi1-eliminate-opcode-tests-on-mr-deref.patch new file mode 100644 index 00000000000..8ad093f27fc --- /dev/null +++ b/queue-5.0/ib-hfi1-eliminate-opcode-tests-on-mr-deref.patch @@ -0,0 +1,52 @@ +From a5e08b29a75e5458acdbf67a9d38011ac84211ed Mon Sep 17 00:00:00 2001 +From: Kaike Wan +Date: Mon, 18 Mar 2019 09:55:39 -0700 +Subject: IB/hfi1: Eliminate opcode tests on mr deref + +[ Upstream commit a8639a79e85c18c16c10089edd589c7948f19bbd ] + +When an old ack_queue entry is used to store an incoming request, it may +need to clean up the old entry if it is still referencing the +MR. Originally only RDMA READ request needed to reference MR on the +responder side and therefore the opcode was tested when cleaning up the +old entry. The introduction of tid rdma specific operations in the +ack_queue makes the specific opcode tests wrong. Multiple opcodes (RDMA +READ, TID RDMA READ, and TID RDMA WRITE) may need MR ref cleanup. + +Remove the opcode specific tests associated with the ack_queue. + +Fixes: f48ad614c100 ("IB/hfi1: Move driver out of staging") +Signed-off-by: Mike Marciniszyn +Signed-off-by: Kaike Wan +Signed-off-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hfi1/rc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c +index be603f35d7e47..cfde43b1df960 100644 +--- a/drivers/infiniband/hw/hfi1/rc.c ++++ b/drivers/infiniband/hw/hfi1/rc.c +@@ -2302,7 +2302,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet) + update_ack_queue(qp, next); + } + e = &qp->s_ack_queue[qp->r_head_ack_queue]; +- if (e->opcode == OP(RDMA_READ_REQUEST) && e->rdma_sge.mr) { ++ if (e->rdma_sge.mr) { + rvt_put_mr(e->rdma_sge.mr); + e->rdma_sge.mr = NULL; + } +@@ -2376,7 +2376,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet) + update_ack_queue(qp, next); + } + e = &qp->s_ack_queue[qp->r_head_ack_queue]; +- if (e->opcode == OP(RDMA_READ_REQUEST) && e->rdma_sge.mr) { ++ if (e->rdma_sge.mr) { + rvt_put_mr(e->rdma_sge.mr); + e->rdma_sge.mr = NULL; + } +-- +2.20.1 + diff --git a/queue-5.0/ib-hfi1-fix-the-allocation-of-rsm-table.patch b/queue-5.0/ib-hfi1-fix-the-allocation-of-rsm-table.patch new file mode 100644 index 00000000000..c9c01dd6881 --- /dev/null +++ b/queue-5.0/ib-hfi1-fix-the-allocation-of-rsm-table.patch @@ -0,0 +1,101 @@ +From e4c23ac8c2ef589764997add626a226076f59468 Mon Sep 17 00:00:00 2001 +From: Kaike Wan +Date: Mon, 18 Mar 2019 09:55:49 -0700 +Subject: IB/hfi1: Fix the allocation of RSM table + +[ Upstream commit d0294344470e6b52d097aa7369173f32d11f2f52 ] + +The receive side mapping (RSM) on hfi1 hardware is a special +matching mechanism to direct an incoming packet to a given +hardware receive context. It has 4 instances of matching capabilities +(RSM0 - RSM3) that share the same RSM table (RMT). The RMT has a total of +256 entries, each of which points to a receive context. + +Currently, three instances of RSM have been used: +1. RSM0 by QOS; +2. RSM1 by PSM FECN; +3. RSM2 by VNIC. + +Each RSM instance should reserve enough entries in RMT to function +properly. Since both PSM and VNIC could allocate any receive context +between dd->first_dyn_alloc_ctxt and dd->num_rcv_contexts, PSM FECN must +reserve enough RMT entries to cover the entire receive context index +range (dd->num_rcv_contexts - dd->first_dyn_alloc_ctxt) instead of only +the user receive contexts allocated for PSM +(dd->num_user_contexts). Consequently, the sizing of +dd->num_user_contexts in set_up_context_variables is incorrect. + +Fixes: 2280740f01ae ("IB/hfi1: Virtual Network Interface Controller (VNIC) HW support") +Reviewed-by: Mike Marciniszyn +Reviewed-by: Michael J. Ruhl +Signed-off-by: Kaike Wan +Signed-off-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hfi1/chip.c | 26 +++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) + +diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c +index b443642eac021..0ae05e9249b39 100644 +--- a/drivers/infiniband/hw/hfi1/chip.c ++++ b/drivers/infiniband/hw/hfi1/chip.c +@@ -13219,7 +13219,7 @@ static int set_up_context_variables(struct hfi1_devdata *dd) + int total_contexts; + int ret; + unsigned ngroups; +- int qos_rmt_count; ++ int rmt_count; + int user_rmt_reduced; + u32 n_usr_ctxts; + u32 send_contexts = chip_send_contexts(dd); +@@ -13281,10 +13281,20 @@ static int set_up_context_variables(struct hfi1_devdata *dd) + n_usr_ctxts = rcv_contexts - total_contexts; + } + +- /* each user context requires an entry in the RMT */ +- qos_rmt_count = qos_rmt_entries(dd, NULL, NULL); +- if (qos_rmt_count + n_usr_ctxts > NUM_MAP_ENTRIES) { +- user_rmt_reduced = NUM_MAP_ENTRIES - qos_rmt_count; ++ /* ++ * The RMT entries are currently allocated as shown below: ++ * 1. QOS (0 to 128 entries); ++ * 2. FECN for PSM (num_user_contexts + num_vnic_contexts); ++ * 3. VNIC (num_vnic_contexts). ++ * It should be noted that PSM FECN oversubscribe num_vnic_contexts ++ * entries of RMT because both VNIC and PSM could allocate any receive ++ * context between dd->first_dyn_alloc_text and dd->num_rcv_contexts, ++ * and PSM FECN must reserve an RMT entry for each possible PSM receive ++ * context. ++ */ ++ rmt_count = qos_rmt_entries(dd, NULL, NULL) + (num_vnic_contexts * 2); ++ if (rmt_count + n_usr_ctxts > NUM_MAP_ENTRIES) { ++ user_rmt_reduced = NUM_MAP_ENTRIES - rmt_count; + dd_dev_err(dd, + "RMT size is reducing the number of user receive contexts from %u to %d\n", + n_usr_ctxts, +@@ -14272,9 +14282,11 @@ static void init_user_fecn_handling(struct hfi1_devdata *dd, + u64 reg; + int i, idx, regoff, regidx; + u8 offset; ++ u32 total_cnt; + + /* there needs to be enough room in the map table */ +- if (rmt->used + dd->num_user_contexts >= NUM_MAP_ENTRIES) { ++ total_cnt = dd->num_rcv_contexts - dd->first_dyn_alloc_ctxt; ++ if (rmt->used + total_cnt >= NUM_MAP_ENTRIES) { + dd_dev_err(dd, "User FECN handling disabled - too many user contexts allocated\n"); + return; + } +@@ -14328,7 +14340,7 @@ static void init_user_fecn_handling(struct hfi1_devdata *dd, + /* add rule 1 */ + add_rsm_rule(dd, RSM_INS_FECN, &rrd); + +- rmt->used += dd->num_user_contexts; ++ rmt->used += total_cnt; + } + + /* Initialize RSM for VNIC */ +-- +2.20.1 + diff --git a/queue-5.0/iommu-amd-set-exclusion-range-correctly.patch b/queue-5.0/iommu-amd-set-exclusion-range-correctly.patch new file mode 100644 index 00000000000..4eec62c6358 --- /dev/null +++ b/queue-5.0/iommu-amd-set-exclusion-range-correctly.patch @@ -0,0 +1,38 @@ +From c72c23c4645ff45a642d94bb0c1e9404ae368fe8 Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Fri, 12 Apr 2019 12:50:31 +0200 +Subject: iommu/amd: Set exclusion range correctly + +[ Upstream commit 3c677d206210f53a4be972211066c0f1cd47fe12 ] + +The exlcusion range limit register needs to contain the +base-address of the last page that is part of the range, as +bits 0-11 of this register are treated as 0xfff by the +hardware for comparisons. + +So correctly set the exclusion range in the hardware to the +last page which is _in_ the range. + +Fixes: b2026aa2dce44 ('x86, AMD IOMMU: add functions for programming IOMMU MMIO space') +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd_iommu_init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c +index 84fa5b22371e8..e8a2efe0afce0 100644 +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -358,7 +358,7 @@ static void iommu_write_l2(struct amd_iommu *iommu, u8 address, u32 val) + static void iommu_set_exclusion_range(struct amd_iommu *iommu) + { + u64 start = iommu->exclusion_start & PAGE_MASK; +- u64 limit = (start + iommu->exclusion_length) & PAGE_MASK; ++ u64 limit = (start + iommu->exclusion_length - 1) & PAGE_MASK; + u64 entry; + + if (!iommu->exclusion_start) +-- +2.20.1 + diff --git a/queue-5.0/iov_iter-fix-build-error-without-config_crypto.patch b/queue-5.0/iov_iter-fix-build-error-without-config_crypto.patch new file mode 100644 index 00000000000..79d2677c21c --- /dev/null +++ b/queue-5.0/iov_iter-fix-build-error-without-config_crypto.patch @@ -0,0 +1,49 @@ +From d4feed11bef9ea86855bc91da9925c6ef24e122a Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Thu, 4 Apr 2019 10:31:14 +0800 +Subject: iov_iter: Fix build error without CONFIG_CRYPTO + +[ Upstream commit 27fad74a5a77fe2e1f876db7bf27efcf2ec304b2 ] + +If CONFIG_CRYPTO is not set or set to m, +gcc building warn this: + +lib/iov_iter.o: In function `hash_and_copy_to_iter': +iov_iter.c:(.text+0x9129): undefined reference to `crypto_stats_get' +iov_iter.c:(.text+0x9152): undefined reference to `crypto_stats_ahash_update' + +Reported-by: Hulk Robot +Fixes: d05f443554b3 ("iov_iter: introduce hash_and_copy_to_iter helper") +Suggested-by: Al Viro +Signed-off-by: YueHaibing +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + lib/iov_iter.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/iov_iter.c b/lib/iov_iter.c +index be4bd627caf06..a0d1cd88f903f 100644 +--- a/lib/iov_iter.c ++++ b/lib/iov_iter.c +@@ -1515,6 +1515,7 @@ EXPORT_SYMBOL(csum_and_copy_to_iter); + size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp, + struct iov_iter *i) + { ++#ifdef CONFIG_CRYPTO + struct ahash_request *hash = hashp; + struct scatterlist sg; + size_t copied; +@@ -1524,6 +1525,9 @@ size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp, + ahash_request_set_crypt(hash, &sg, NULL, copied); + crypto_ahash_update(hash); + return copied; ++#else ++ return 0; ++#endif + } + EXPORT_SYMBOL(hash_and_copy_to_iter); + +-- +2.20.1 + diff --git a/queue-5.0/keys-trusted-fix-wvarags-warning.patch b/queue-5.0/keys-trusted-fix-wvarags-warning.patch new file mode 100644 index 00000000000..416554b87a5 --- /dev/null +++ b/queue-5.0/keys-trusted-fix-wvarags-warning.patch @@ -0,0 +1,83 @@ +From 08cb7bed66b34820dca4ddb242813ffbdbe76b78 Mon Sep 17 00:00:00 2001 +From: "ndesaulniers@google.com" +Date: Mon, 22 Oct 2018 16:43:57 -0700 +Subject: KEYS: trusted: fix -Wvarags warning + +[ Upstream commit be24b37e22c20cbaa891971616784dd0f35211e8 ] + +Fixes the warning reported by Clang: +security/keys/trusted.c:146:17: warning: passing an object that +undergoes default + argument promotion to 'va_start' has undefined behavior [-Wvarargs] + va_start(argp, h3); + ^ +security/keys/trusted.c:126:37: note: parameter of type 'unsigned +char' is declared here +unsigned char *h2, unsigned char h3, ...) + ^ +Specifically, it seems that both the C90 (4.8.1.1) and C11 (7.16.1.4) +standards explicitly call this out as undefined behavior: + +The parameter parmN is the identifier of the rightmost parameter in +the variable parameter list in the function definition (the one just +before the ...). If the parameter parmN is declared with ... or with a +type that is not compatible with the type that results after +application of the default argument promotions, the behavior is +undefined. + +Link: https://github.com/ClangBuiltLinux/linux/issues/41 +Link: https://www.eskimo.com/~scs/cclass/int/sx11c.html +Suggested-by: David Laight +Suggested-by: Denis Kenzior +Suggested-by: James Bottomley +Suggested-by: Nathan Chancellor +Signed-off-by: Nick Desaulniers +Reviewed-by: Nathan Chancellor +Tested-by: Nathan Chancellor +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: James Morris +Signed-off-by: Sasha Levin +--- + include/keys/trusted.h | 2 +- + security/keys/trusted.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/keys/trusted.h b/include/keys/trusted.h +index adbcb68178260..0071298b9b28e 100644 +--- a/include/keys/trusted.h ++++ b/include/keys/trusted.h +@@ -38,7 +38,7 @@ enum { + + int TSS_authhmac(unsigned char *digest, const unsigned char *key, + unsigned int keylen, unsigned char *h1, +- unsigned char *h2, unsigned char h3, ...); ++ unsigned char *h2, unsigned int h3, ...); + int TSS_checkhmac1(unsigned char *buffer, + const uint32_t command, + const unsigned char *ononce, +diff --git a/security/keys/trusted.c b/security/keys/trusted.c +index 4d98f4f87236c..94d2b28c7c223 100644 +--- a/security/keys/trusted.c ++++ b/security/keys/trusted.c +@@ -123,7 +123,7 @@ static int TSS_rawhmac(unsigned char *digest, const unsigned char *key, + */ + int TSS_authhmac(unsigned char *digest, const unsigned char *key, + unsigned int keylen, unsigned char *h1, +- unsigned char *h2, unsigned char h3, ...) ++ unsigned char *h2, unsigned int h3, ...) + { + unsigned char paramdigest[SHA1_DIGEST_SIZE]; + struct sdesc *sdesc; +@@ -139,7 +139,7 @@ int TSS_authhmac(unsigned char *digest, const unsigned char *key, + return PTR_ERR(sdesc); + } + +- c = h3; ++ c = !!h3; + ret = crypto_shash_init(&sdesc->shash); + if (ret < 0) + goto out; +-- +2.20.1 + diff --git a/queue-5.0/linux-kernel.h-use-parentheses-around-argument-in-u6.patch b/queue-5.0/linux-kernel.h-use-parentheses-around-argument-in-u6.patch new file mode 100644 index 00000000000..73716bb4762 --- /dev/null +++ b/queue-5.0/linux-kernel.h-use-parentheses-around-argument-in-u6.patch @@ -0,0 +1,70 @@ +From e231ad027fd94ba4595f06b00c284a621c2a4e6d Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Fri, 29 Mar 2019 22:46:49 +0100 +Subject: linux/kernel.h: Use parentheses around argument in u64_to_user_ptr() + +[ Upstream commit a0fe2c6479aab5723239b315ef1b552673f434a3 ] + +Use parentheses around uses of the argument in u64_to_user_ptr() to +ensure that the cast doesn't apply to part of the argument. + +There are existing uses of the macro of the form + + u64_to_user_ptr(A + B) + +which expands to + + (void __user *)(uintptr_t)A + B + +(the cast applies to the first operand of the addition, the addition +is a pointer addition). This happens to still work as intended, the +semantic difference doesn't cause a difference in behavior. + +But I want to use u64_to_user_ptr() with a ternary operator in the +argument, like so: + + u64_to_user_ptr(A ? B : C) + +This currently doesn't work as intended. + +Signed-off-by: Jann Horn +Signed-off-by: Borislav Petkov +Reviewed-by: Mukesh Ojha +Cc: Andrei Vagin +Cc: Andrew Morton +Cc: Dan Carpenter +Cc: Greg Kroah-Hartman +Cc: "H. Peter Anvin" +Cc: Ingo Molnar +Cc: Jani Nikula +Cc: Kees Cook +Cc: Masahiro Yamada +Cc: NeilBrown +Cc: Peter Zijlstra +Cc: Qiaowei Ren +Cc: Thomas Gleixner +Cc: x86-ml +Link: https://lkml.kernel.org/r/20190329214652.258477-1-jannh@google.com +Signed-off-by: Sasha Levin +--- + include/linux/kernel.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/kernel.h b/include/linux/kernel.h +index 8f0e68e250a76..fd827b2400596 100644 +--- a/include/linux/kernel.h ++++ b/include/linux/kernel.h +@@ -73,8 +73,8 @@ + + #define u64_to_user_ptr(x) ( \ + { \ +- typecheck(u64, x); \ +- (void __user *)(uintptr_t)x; \ ++ typecheck(u64, (x)); \ ++ (void __user *)(uintptr_t)(x); \ + } \ + ) + +-- +2.20.1 + diff --git a/queue-5.0/mips-kgdb-fix-kgdb-support-for-smp-platforms.patch b/queue-5.0/mips-kgdb-fix-kgdb-support-for-smp-platforms.patch new file mode 100644 index 00000000000..f47d9276cf8 --- /dev/null +++ b/queue-5.0/mips-kgdb-fix-kgdb-support-for-smp-platforms.patch @@ -0,0 +1,53 @@ +From aff39bcb7b93a2fc3db9dda7e641683b8a1ff33a Mon Sep 17 00:00:00 2001 +From: Chong Qiao +Date: Thu, 28 Mar 2019 07:08:01 +0800 +Subject: MIPS: KGDB: fix kgdb support for SMP platforms. + +[ Upstream commit ab8a6d821179ab9bea1a9179f535ccba6330c1ed ] + +KGDB_call_nmi_hook is called by other cpu through smp call. +MIPS smp call is processed in ipi irq handler and regs is saved in + handle_int. +So kgdb_call_nmi_hook get regs by get_irq_regs and regs will be passed + to kgdb_cpu_enter. + +Signed-off-by: Chong Qiao +Reviewed-by: Douglas Anderson +Acked-by: Daniel Thompson +Signed-off-by: Paul Burton +Cc: Ralf Baechle +Cc: James Hogan +Cc: Will Deacon +Cc: Christophe Leroy +Cc: linux-mips@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Cc: QiaoChong +Signed-off-by: Sasha Levin +--- + arch/mips/kernel/kgdb.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c +index 149100e1bc7c4..90f37626100fe 100644 +--- a/arch/mips/kernel/kgdb.c ++++ b/arch/mips/kernel/kgdb.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + static struct hard_trap_info { + unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ +@@ -214,7 +215,7 @@ void kgdb_call_nmi_hook(void *ignored) + old_fs = get_fs(); + set_fs(get_ds()); + +- kgdb_nmicallback(raw_smp_processor_id(), NULL); ++ kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); + + set_fs(old_fs); + } +-- +2.20.1 + diff --git a/queue-5.0/nfsv4.1-fix-incorrect-return-value-in-copy_file_rang.patch b/queue-5.0/nfsv4.1-fix-incorrect-return-value-in-copy_file_rang.patch new file mode 100644 index 00000000000..05037a2e4c3 --- /dev/null +++ b/queue-5.0/nfsv4.1-fix-incorrect-return-value-in-copy_file_rang.patch @@ -0,0 +1,60 @@ +From 3801581bf8a91b1f7a606caa717c089545dabf89 Mon Sep 17 00:00:00 2001 +From: Olga Kornievskaia +Date: Thu, 11 Apr 2019 14:34:18 -0400 +Subject: NFSv4.1 fix incorrect return value in copy_file_range + +[ Upstream commit 0769663b4f580566ef6cdf366f3073dbe8022c39 ] + +According to the NFSv4.2 spec if the input and output file is the +same file, operation should fail with EINVAL. However, linux +copy_file_range() system call has no such restrictions. Therefore, +in such case let's return EOPNOTSUPP and allow VFS to fallback +to doing do_splice_direct(). Also when copy_file_range is called +on an NFSv4.0 or 4.1 mount (ie., a server that doesn't support +COPY functionality), we also need to return EOPNOTSUPP and +fallback to a regular copy. + +Fixes xfstest generic/075, generic/091, generic/112, generic/263 +for all NFSv4.x versions. + +Signed-off-by: Olga Kornievskaia +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs42proc.c | 3 --- + fs/nfs/nfs4file.c | 4 +++- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c +index fed06fd9998d3..94f98e190e632 100644 +--- a/fs/nfs/nfs42proc.c ++++ b/fs/nfs/nfs42proc.c +@@ -329,9 +329,6 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, + }; + ssize_t err, err2; + +- if (!nfs_server_capable(file_inode(dst), NFS_CAP_COPY)) +- return -EOPNOTSUPP; +- + src_lock = nfs_get_lock_context(nfs_file_open_context(src)); + if (IS_ERR(src_lock)) + return PTR_ERR(src_lock); +diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c +index 45b2322e092d2..00d17198ee12a 100644 +--- a/fs/nfs/nfs4file.c ++++ b/fs/nfs/nfs4file.c +@@ -133,8 +133,10 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + size_t count, unsigned int flags) + { ++ if (!nfs_server_capable(file_inode(file_out), NFS_CAP_COPY)) ++ return -EOPNOTSUPP; + if (file_inode(file_in) == file_inode(file_out)) +- return -EINVAL; ++ return -EOPNOTSUPP; + return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count); + } + +-- +2.20.1 + diff --git a/queue-5.0/nvme-cancel-request-synchronously.patch b/queue-5.0/nvme-cancel-request-synchronously.patch new file mode 100644 index 00000000000..5a6529af0d3 --- /dev/null +++ b/queue-5.0/nvme-cancel-request-synchronously.patch @@ -0,0 +1,43 @@ +From 094af49b7d270557fd2a61bcaa32712a39c33a98 Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Tue, 9 Apr 2019 06:31:22 +0800 +Subject: nvme: cancel request synchronously + +[ Upstream commit eb3afb75b57c28599af0dfa03a99579d410749e9 ] + +nvme_cancel_request() is used in error handler, and it is always +reliable to cancel request synchronously, and avoids possible race +in which request may be completed after real hw queue is destroyed. + +One issue is reported by our customer on NVMe RDMA, in which freed ib +queue pair may be used in nvme_rdma_complete_rq(). + +Cc: Sagi Grimberg +Cc: Bart Van Assche +Cc: James Smart +Cc: linux-nvme@lists.infradead.org +Reviewed-by: Keith Busch +Reviewed-by: Christoph Hellwig +Signed-off-by: Ming Lei +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 6a9dd68c0f4fe..4c4413ad3ceb3 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -291,7 +291,7 @@ bool nvme_cancel_request(struct request *req, void *data, bool reserved) + "Cancelling I/O %d", req->tag); + + nvme_req(req)->status = NVME_SC_ABORT_REQ; +- blk_mq_complete_request(req); ++ blk_mq_complete_request_sync(req); + return true; + } + EXPORT_SYMBOL_GPL(nvme_cancel_request); +-- +2.20.1 + diff --git a/queue-5.0/nvme-fc-correct-csn-initialization-and-increments-on.patch b/queue-5.0/nvme-fc-correct-csn-initialization-and-increments-on.patch new file mode 100644 index 00000000000..1cddb810751 --- /dev/null +++ b/queue-5.0/nvme-fc-correct-csn-initialization-and-increments-on.patch @@ -0,0 +1,96 @@ +From 943566bbdf4016156d69982982e211c3ea6e2784 Mon Sep 17 00:00:00 2001 +From: James Smart +Date: Mon, 8 Apr 2019 11:15:19 -0700 +Subject: nvme-fc: correct csn initialization and increments on error + +[ Upstream commit 67f471b6ed3b09033c4ac77ea03f92afdb1989fe ] + +This patch fixes a long-standing bug that initialized the FC-NVME +cmnd iu CSN value to 1. Early FC-NVME specs had the connection starting +with CSN=1. By the time the spec reached approval, the language had +changed to state a connection should start with CSN=0. This patch +corrects the initialization value for FC-NVME connections. + +Additionally, in reviewing the transport, the CSN value is assigned to +the new IU early in the start routine. It's possible that a later dma +map request may fail, causing the command to never be sent to the +controller. Change the location of the assignment so that it is +immediately prior to calling the lldd. Add a comment block to explain +the impacts if the lldd were to additionally fail sending the command. + +Signed-off-by: Dick Kennedy +Signed-off-by: James Smart +Reviewed-by: Ewan D. Milne +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/fc.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c +index c37d5bbd72ab6..8625b73d94bf7 100644 +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -1857,7 +1857,7 @@ nvme_fc_init_queue(struct nvme_fc_ctrl *ctrl, int idx) + memset(queue, 0, sizeof(*queue)); + queue->ctrl = ctrl; + queue->qnum = idx; +- atomic_set(&queue->csn, 1); ++ atomic_set(&queue->csn, 0); + queue->dev = ctrl->dev; + + if (idx > 0) +@@ -1899,7 +1899,7 @@ nvme_fc_free_queue(struct nvme_fc_queue *queue) + */ + + queue->connection_id = 0; +- atomic_set(&queue->csn, 1); ++ atomic_set(&queue->csn, 0); + } + + static void +@@ -2195,7 +2195,6 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, + { + struct nvme_fc_cmd_iu *cmdiu = &op->cmd_iu; + struct nvme_command *sqe = &cmdiu->sqe; +- u32 csn; + int ret, opstate; + + /* +@@ -2210,8 +2209,6 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, + + /* format the FC-NVME CMD IU and fcp_req */ + cmdiu->connection_id = cpu_to_be64(queue->connection_id); +- csn = atomic_inc_return(&queue->csn); +- cmdiu->csn = cpu_to_be32(csn); + cmdiu->data_len = cpu_to_be32(data_len); + switch (io_dir) { + case NVMEFC_FCP_WRITE: +@@ -2269,11 +2266,24 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, + if (!(op->flags & FCOP_FLAGS_AEN)) + blk_mq_start_request(op->rq); + ++ cmdiu->csn = cpu_to_be32(atomic_inc_return(&queue->csn)); + ret = ctrl->lport->ops->fcp_io(&ctrl->lport->localport, + &ctrl->rport->remoteport, + queue->lldd_handle, &op->fcp_req); + + if (ret) { ++ /* ++ * If the lld fails to send the command is there an issue with ++ * the csn value? If the command that fails is the Connect, ++ * no - as the connection won't be live. If it is a command ++ * post-connect, it's possible a gap in csn may be created. ++ * Does this matter? As Linux initiators don't send fused ++ * commands, no. The gap would exist, but as there's nothing ++ * that depends on csn order to be delivered on the target ++ * side, it shouldn't hurt. It would be difficult for a ++ * target to even detect the csn gap as it has no idea when the ++ * cmd with the csn was supposed to arrive. ++ */ + opstate = atomic_xchg(&op->state, FCPOP_STATE_COMPLETE); + __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate); + +-- +2.20.1 + diff --git a/queue-5.0/nvmet-fix-discover-log-page-when-offsets-are-used.patch b/queue-5.0/nvmet-fix-discover-log-page-when-offsets-are-used.patch new file mode 100644 index 00000000000..78c5f261699 --- /dev/null +++ b/queue-5.0/nvmet-fix-discover-log-page-when-offsets-are-used.patch @@ -0,0 +1,196 @@ +From 725f95a0e35da96c404dcbcce719706df2598bf7 Mon Sep 17 00:00:00 2001 +From: Keith Busch +Date: Tue, 9 Apr 2019 10:03:59 -0600 +Subject: nvmet: fix discover log page when offsets are used + +[ Upstream commit d808b7f759b50acf0784ce6230ffa63e12ef465d ] + +The nvme target hadn't been taking the Get Log Page offset parameter +into consideration, and so has been returning corrupted log pages when +offsets are used. Since many tools, including nvme-cli, split the log +request to 4k, we've been breaking discovery log responses when more +than 3 subsystems exist. + +Fix the returned data by internally generating the entire discovery +log page and copying only the requested bytes into the user buffer. The +command log page offset type has been modified to a native __le64 to +make it easier to extract the value from a command. + +Signed-off-by: Keith Busch +Tested-by: Minwoo Im +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Hannes Reinecke +Reviewed-by: James Smart +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/admin-cmd.c | 5 +++ + drivers/nvme/target/discovery.c | 68 ++++++++++++++++++++++----------- + drivers/nvme/target/nvmet.h | 1 + + include/linux/nvme.h | 9 ++++- + 4 files changed, 58 insertions(+), 25 deletions(-) + +diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c +index 11baeb14c3881..8fdae510c5ac0 100644 +--- a/drivers/nvme/target/admin-cmd.c ++++ b/drivers/nvme/target/admin-cmd.c +@@ -32,6 +32,11 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd) + return len; + } + ++u64 nvmet_get_log_page_offset(struct nvme_command *cmd) ++{ ++ return le64_to_cpu(cmd->get_log_page.lpo); ++} ++ + static void nvmet_execute_get_log_page_noop(struct nvmet_req *req) + { + nvmet_req_complete(req, nvmet_zero_sgl(req, 0, req->data_len)); +diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c +index d2cb71a0b419d..389c1a90197d9 100644 +--- a/drivers/nvme/target/discovery.c ++++ b/drivers/nvme/target/discovery.c +@@ -139,54 +139,76 @@ static void nvmet_set_disc_traddr(struct nvmet_req *req, struct nvmet_port *port + memcpy(traddr, port->disc_addr.traddr, NVMF_TRADDR_SIZE); + } + ++static size_t discovery_log_entries(struct nvmet_req *req) ++{ ++ struct nvmet_ctrl *ctrl = req->sq->ctrl; ++ struct nvmet_subsys_link *p; ++ struct nvmet_port *r; ++ size_t entries = 0; ++ ++ list_for_each_entry(p, &req->port->subsystems, entry) { ++ if (!nvmet_host_allowed(p->subsys, ctrl->hostnqn)) ++ continue; ++ entries++; ++ } ++ list_for_each_entry(r, &req->port->referrals, entry) ++ entries++; ++ return entries; ++} ++ + static void nvmet_execute_get_disc_log_page(struct nvmet_req *req) + { + const int entry_size = sizeof(struct nvmf_disc_rsp_page_entry); + struct nvmet_ctrl *ctrl = req->sq->ctrl; + struct nvmf_disc_rsp_page_hdr *hdr; ++ u64 offset = nvmet_get_log_page_offset(req->cmd); + size_t data_len = nvmet_get_log_page_len(req->cmd); +- size_t alloc_len = max(data_len, sizeof(*hdr)); +- int residual_len = data_len - sizeof(*hdr); ++ size_t alloc_len; + struct nvmet_subsys_link *p; + struct nvmet_port *r; + u32 numrec = 0; + u16 status = 0; ++ void *buffer; ++ ++ /* Spec requires dword aligned offsets */ ++ if (offset & 0x3) { ++ status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ goto out; ++ } + + /* + * Make sure we're passing at least a buffer of response header size. + * If host provided data len is less than the header size, only the + * number of bytes requested by host will be sent to host. + */ +- hdr = kzalloc(alloc_len, GFP_KERNEL); +- if (!hdr) { ++ down_read(&nvmet_config_sem); ++ alloc_len = sizeof(*hdr) + entry_size * discovery_log_entries(req); ++ buffer = kzalloc(alloc_len, GFP_KERNEL); ++ if (!buffer) { ++ up_read(&nvmet_config_sem); + status = NVME_SC_INTERNAL; + goto out; + } + +- down_read(&nvmet_config_sem); ++ hdr = buffer; + list_for_each_entry(p, &req->port->subsystems, entry) { ++ char traddr[NVMF_TRADDR_SIZE]; ++ + if (!nvmet_host_allowed(p->subsys, ctrl->hostnqn)) + continue; +- if (residual_len >= entry_size) { +- char traddr[NVMF_TRADDR_SIZE]; +- +- nvmet_set_disc_traddr(req, req->port, traddr); +- nvmet_format_discovery_entry(hdr, req->port, +- p->subsys->subsysnqn, traddr, +- NVME_NQN_NVME, numrec); +- residual_len -= entry_size; +- } ++ ++ nvmet_set_disc_traddr(req, req->port, traddr); ++ nvmet_format_discovery_entry(hdr, req->port, ++ p->subsys->subsysnqn, traddr, ++ NVME_NQN_NVME, numrec); + numrec++; + } + + list_for_each_entry(r, &req->port->referrals, entry) { +- if (residual_len >= entry_size) { +- nvmet_format_discovery_entry(hdr, r, +- NVME_DISC_SUBSYS_NAME, +- r->disc_addr.traddr, +- NVME_NQN_DISC, numrec); +- residual_len -= entry_size; +- } ++ nvmet_format_discovery_entry(hdr, r, ++ NVME_DISC_SUBSYS_NAME, ++ r->disc_addr.traddr, ++ NVME_NQN_DISC, numrec); + numrec++; + } + +@@ -198,8 +220,8 @@ static void nvmet_execute_get_disc_log_page(struct nvmet_req *req) + + up_read(&nvmet_config_sem); + +- status = nvmet_copy_to_sgl(req, 0, hdr, data_len); +- kfree(hdr); ++ status = nvmet_copy_to_sgl(req, 0, buffer + offset, data_len); ++ kfree(buffer); + out: + nvmet_req_complete(req, status); + } +diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h +index 3e4719fdba854..d253c45c1aa6e 100644 +--- a/drivers/nvme/target/nvmet.h ++++ b/drivers/nvme/target/nvmet.h +@@ -436,6 +436,7 @@ u16 nvmet_copy_from_sgl(struct nvmet_req *req, off_t off, void *buf, + u16 nvmet_zero_sgl(struct nvmet_req *req, off_t off, size_t len); + + u32 nvmet_get_log_page_len(struct nvme_command *cmd); ++u64 nvmet_get_log_page_offset(struct nvme_command *cmd); + + extern struct list_head *nvmet_ports; + void nvmet_port_disc_changed(struct nvmet_port *port, +diff --git a/include/linux/nvme.h b/include/linux/nvme.h +index bbcc83886899c..7ba0368f16e6e 100644 +--- a/include/linux/nvme.h ++++ b/include/linux/nvme.h +@@ -975,8 +975,13 @@ struct nvme_get_log_page_command { + __le16 numdl; + __le16 numdu; + __u16 rsvd11; +- __le32 lpol; +- __le32 lpou; ++ union { ++ struct { ++ __le32 lpol; ++ __le32 lpou; ++ }; ++ __le64 lpo; ++ }; + __u32 rsvd14[2]; + }; + +-- +2.20.1 + diff --git a/queue-5.0/objtool-add-rewind_stack_do_exit-to-the-noreturn-lis.patch b/queue-5.0/objtool-add-rewind_stack_do_exit-to-the-noreturn-lis.patch new file mode 100644 index 00000000000..c56222b2e4a --- /dev/null +++ b/queue-5.0/objtool-add-rewind_stack_do_exit-to-the-noreturn-lis.patch @@ -0,0 +1,36 @@ +From 0caf52ee3faef4f5190c58ac7fff6f19b57412af Mon Sep 17 00:00:00 2001 +From: Josh Poimboeuf +Date: Thu, 4 Apr 2019 12:17:35 -0500 +Subject: objtool: Add rewind_stack_do_exit() to the noreturn list + +[ Upstream commit 4fa5ecda2bf96be7464eb406df8aba9d89260227 ] + +This fixes the following warning seen on GCC 7.3: + + arch/x86/kernel/dumpstack.o: warning: objtool: oops_end() falls through to next function show_regs() + +Reported-by: kbuild test robot +Signed-off-by: Josh Poimboeuf +Signed-off-by: Thomas Gleixner +Cc: Peter Zijlstra +Link: https://lkml.kernel.org/r/3418ebf5a5a9f6ed7e80954c741c0b904b67b5dc.1554398240.git.jpoimboe@redhat.com +Signed-off-by: Sasha Levin +--- + tools/objtool/check.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index 5dde107083c60..479196aeb4096 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -165,6 +165,7 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func, + "fortify_panic", + "usercopy_abort", + "machine_real_restart", ++ "rewind_stack_do_exit", + }; + + if (func->bind == STB_WEAK) +-- +2.20.1 + diff --git a/queue-5.0/perf-core-fix-perf_event_disable_inatomic-race.patch b/queue-5.0/perf-core-fix-perf_event_disable_inatomic-race.patch new file mode 100644 index 00000000000..c0d688d1cd4 --- /dev/null +++ b/queue-5.0/perf-core-fix-perf_event_disable_inatomic-race.patch @@ -0,0 +1,187 @@ +From 7b5f877cd62c2e9ab6515f49f62db6c29945d147 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Thu, 4 Apr 2019 15:03:00 +0200 +Subject: perf/core: Fix perf_event_disable_inatomic() race + +[ Upstream commit 1d54ad944074010609562da5c89e4f5df2f4e5db ] + +Thomas-Mich Richter reported he triggered a WARN()ing from event_function_local() +on his s390. The problem boils down to: + + CPU-A CPU-B + + perf_event_overflow() + perf_event_disable_inatomic() + @pending_disable = 1 + irq_work_queue(); + + sched-out + event_sched_out() + @pending_disable = 0 + + sched-in + perf_event_overflow() + perf_event_disable_inatomic() + @pending_disable = 1; + irq_work_queue(); // FAILS + + irq_work_run() + perf_pending_event() + if (@pending_disable) + perf_event_disable_local(); // WHOOPS + +The problem exists in generic, but s390 is particularly sensitive +because it doesn't implement arch_irq_work_raise(), nor does it call +irq_work_run() from it's PMU interrupt handler (nor would that be +sufficient in this case, because s390 also generates +perf_event_overflow() from pmu::stop). Add to that the fact that s390 +is a virtual architecture and (virtual) CPU-A can stall long enough +for the above race to happen, even if it would self-IPI. + +Adding a irq_work_sync() to event_sched_in() would work for all hardare +PMUs that properly use irq_work_run() but fails for software PMUs. + +Instead encode the CPU number in @pending_disable, such that we can +tell which CPU requested the disable. This then allows us to detect +the above scenario and even redirect the IPI to make up for the failed +queue. + +Reported-by: Thomas-Mich Richter +Tested-by: Thomas Richter +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Mark Rutland +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Heiko Carstens +Cc: Hendrik Brueckner +Cc: Jiri Olsa +Cc: Kees Cook +Cc: Linus Torvalds +Cc: Martin Schwidefsky +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Signed-off-by: Ingo Molnar +Signed-off-by: Sasha Levin +--- + kernel/events/core.c | 52 ++++++++++++++++++++++++++++++------- + kernel/events/ring_buffer.c | 4 +-- + 2 files changed, 45 insertions(+), 11 deletions(-) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 2e2305a810470..124e1e3d06b92 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -2007,8 +2007,8 @@ event_sched_out(struct perf_event *event, + event->pmu->del(event, 0); + event->oncpu = -1; + +- if (event->pending_disable) { +- event->pending_disable = 0; ++ if (READ_ONCE(event->pending_disable) >= 0) { ++ WRITE_ONCE(event->pending_disable, -1); + state = PERF_EVENT_STATE_OFF; + } + perf_event_set_state(event, state); +@@ -2196,7 +2196,8 @@ EXPORT_SYMBOL_GPL(perf_event_disable); + + void perf_event_disable_inatomic(struct perf_event *event) + { +- event->pending_disable = 1; ++ WRITE_ONCE(event->pending_disable, smp_processor_id()); ++ /* can fail, see perf_pending_event_disable() */ + irq_work_queue(&event->pending); + } + +@@ -5803,10 +5804,45 @@ void perf_event_wakeup(struct perf_event *event) + } + } + ++static void perf_pending_event_disable(struct perf_event *event) ++{ ++ int cpu = READ_ONCE(event->pending_disable); ++ ++ if (cpu < 0) ++ return; ++ ++ if (cpu == smp_processor_id()) { ++ WRITE_ONCE(event->pending_disable, -1); ++ perf_event_disable_local(event); ++ return; ++ } ++ ++ /* ++ * CPU-A CPU-B ++ * ++ * perf_event_disable_inatomic() ++ * @pending_disable = CPU-A; ++ * irq_work_queue(); ++ * ++ * sched-out ++ * @pending_disable = -1; ++ * ++ * sched-in ++ * perf_event_disable_inatomic() ++ * @pending_disable = CPU-B; ++ * irq_work_queue(); // FAILS ++ * ++ * irq_work_run() ++ * perf_pending_event() ++ * ++ * But the event runs on CPU-B and wants disabling there. ++ */ ++ irq_work_queue_on(&event->pending, cpu); ++} ++ + static void perf_pending_event(struct irq_work *entry) + { +- struct perf_event *event = container_of(entry, +- struct perf_event, pending); ++ struct perf_event *event = container_of(entry, struct perf_event, pending); + int rctx; + + rctx = perf_swevent_get_recursion_context(); +@@ -5815,10 +5851,7 @@ static void perf_pending_event(struct irq_work *entry) + * and we won't recurse 'further'. + */ + +- if (event->pending_disable) { +- event->pending_disable = 0; +- perf_event_disable_local(event); +- } ++ perf_pending_event_disable(event); + + if (event->pending_wakeup) { + event->pending_wakeup = 0; +@@ -9998,6 +10031,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, + + + init_waitqueue_head(&event->waitq); ++ event->pending_disable = -1; + init_irq_work(&event->pending, perf_pending_event); + + mutex_init(&event->mmap_mutex); +diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c +index dbd7656b4f737..a5fc56a654fd3 100644 +--- a/kernel/events/ring_buffer.c ++++ b/kernel/events/ring_buffer.c +@@ -393,7 +393,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle, + * store that will be enabled on successful return + */ + if (!handle->size) { /* A, matches D */ +- event->pending_disable = 1; ++ event->pending_disable = smp_processor_id(); + perf_output_wakeup(handle); + local_set(&rb->aux_nest, 0); + goto err_put; +@@ -478,7 +478,7 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size) + + if (wakeup) { + if (handle->aux_flags & PERF_AUX_FLAG_TRUNCATED) +- handle->event->pending_disable = 1; ++ handle->event->pending_disable = smp_processor_id(); + perf_output_wakeup(handle); + } + +-- +2.20.1 + diff --git a/queue-5.0/perf-x86-intel-fix-handling-of-wakeup_events-for-mul.patch b/queue-5.0/perf-x86-intel-fix-handling-of-wakeup_events-for-mul.patch new file mode 100644 index 00000000000..79013275c52 --- /dev/null +++ b/queue-5.0/perf-x86-intel-fix-handling-of-wakeup_events-for-mul.patch @@ -0,0 +1,59 @@ +From d42d592d28f7f20ffb580141d16653e90e40a2e0 Mon Sep 17 00:00:00 2001 +From: Stephane Eranian +Date: Wed, 6 Mar 2019 11:50:48 -0800 +Subject: perf/x86/intel: Fix handling of wakeup_events for multi-entry PEBS + +[ Upstream commit 583feb08e7f7ac9d533b446882eb3a54737a6dbb ] + +When an event is programmed with attr.wakeup_events=N (N>0), it means +the caller is interested in getting a user level notification after +N samples have been recorded in the kernel sampling buffer. + +With precise events on Intel processors, the kernel uses PEBS. +The kernel tries minimize sampling overhead by verifying +if the event configuration is compatible with multi-entry PEBS mode. +If so, the kernel is notified only when the buffer has reached its threshold. +Other PEBS operates in single-entry mode, the kenrel is notified for each +PEBS sample. + +The problem is that the current implementation look at frequency +mode and event sample_type but ignores the wakeup_events field. Thus, +it may not be possible to receive a notification after each precise event. + +This patch fixes this problem by disabling multi-entry PEBS if wakeup_events +is non-zero. + +Signed-off-by: Stephane Eranian +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Andi Kleen +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Vince Weaver +Cc: kan.liang@intel.com +Link: https://lkml.kernel.org/r/20190306195048.189514-1-eranian@google.com +Signed-off-by: Ingo Molnar +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index 470d7daa915d9..77353555d491a 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -3184,7 +3184,7 @@ static int intel_pmu_hw_config(struct perf_event *event) + return ret; + + if (event->attr.precise_ip) { +- if (!event->attr.freq) { ++ if (!(event->attr.freq || event->attr.wakeup_events)) { + event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; + if (!(event->attr.sample_type & + ~intel_pmu_large_pebs_flags(event))) +-- +2.20.1 + diff --git a/queue-5.0/perf-x86-intel-initialize-tfa-msr.patch b/queue-5.0/perf-x86-intel-initialize-tfa-msr.patch new file mode 100644 index 00000000000..404c0dd1d81 --- /dev/null +++ b/queue-5.0/perf-x86-intel-initialize-tfa-msr.patch @@ -0,0 +1,49 @@ +From 1a77a3171ad9b81335a0cf52543e2ff01f21f79d Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Thu, 21 Mar 2019 13:38:49 +0100 +Subject: perf/x86/intel: Initialize TFA MSR + +[ Upstream commit d7262457e35dbe239659e62654e56f8ddb814bed ] + +Stephane reported that the TFA MSR is not initialized by the kernel, +but the TFA bit could set by firmware or as a leftover from a kexec, +which makes the state inconsistent. + +Reported-by: Stephane Eranian +Tested-by: Nelson DSouza +Signed-off-by: Peter Zijlstra (Intel) +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Vince Weaver +Cc: tonyj@suse.com +Link: https://lkml.kernel.org/r/20190321123849.GN6521@hirez.programming.kicks-ass.net +Signed-off-by: Ingo Molnar +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/core.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index 77353555d491a..71fb8b7b29545 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -3563,6 +3563,12 @@ static void intel_pmu_cpu_starting(int cpu) + + cpuc->lbr_sel = NULL; + ++ if (x86_pmu.flags & PMU_FL_TFA) { ++ WARN_ON_ONCE(cpuc->tfa_shadow); ++ cpuc->tfa_shadow = ~0ULL; ++ intel_set_tfa(cpuc, false); ++ } ++ + if (x86_pmu.version > 1) + flip_smm_bit(&x86_pmu.attr_freeze_on_smi); + +-- +2.20.1 + diff --git a/queue-5.0/platform-x86-pmc_atom-drop-__initconst-on-dmi-table.patch b/queue-5.0/platform-x86-pmc_atom-drop-__initconst-on-dmi-table.patch new file mode 100644 index 00000000000..8ba562241da --- /dev/null +++ b/queue-5.0/platform-x86-pmc_atom-drop-__initconst-on-dmi-table.patch @@ -0,0 +1,40 @@ +From 3dbaaf718d74a00c8c608edd1935ccc52d91238f Mon Sep 17 00:00:00 2001 +From: Stephen Boyd +Date: Thu, 11 Apr 2019 10:22:43 -0700 +Subject: platform/x86: pmc_atom: Drop __initconst on dmi table +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit b995dcca7cf12f208cfd95fd9d5768dca7cccec7 ] + +It's used by probe and that isn't an init function. Drop this so that we +don't get a section mismatch. + +Reported-by: kbuild test robot +Cc: David Müller +Cc: Hans de Goede +Cc: Andy Shevchenko +Fixes: 7c2e07130090 ("clk: x86: Add system specific quirk to mark clocks as critical") +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/pmc_atom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c +index eaec2d306481c..c7039f52ad518 100644 +--- a/drivers/platform/x86/pmc_atom.c ++++ b/drivers/platform/x86/pmc_atom.c +@@ -396,7 +396,7 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc) + * Some systems need one or more of their pmc_plt_clks to be + * marked as critical. + */ +-static const struct dmi_system_id critclk_systems[] __initconst = { ++static const struct dmi_system_id critclk_systems[] = { + { + .ident = "MPL CEC1x", + .matches = { +-- +2.20.1 + diff --git a/queue-5.0/rdma-hns-fix-bug-that-caused-srq-creation-to-fail.patch b/queue-5.0/rdma-hns-fix-bug-that-caused-srq-creation-to-fail.patch new file mode 100644 index 00000000000..5312934a01c --- /dev/null +++ b/queue-5.0/rdma-hns-fix-bug-that-caused-srq-creation-to-fail.patch @@ -0,0 +1,79 @@ +From 17808c367486906af71d61dc6ee9ca53b543acab Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Sun, 7 Apr 2019 13:23:38 +0800 +Subject: RDMA/hns: Fix bug that caused srq creation to fail + +[ Upstream commit 4772e03d239484f3461e33c79d721c8ea03f7416 ] + +Due to the incorrect use of the seg and obj information, the position of +the mtt is calculated incorrectly, and the free space of the page is not +enough to store the entire mtt, resulting in access to the next page. This +patch fixes this problem. + + Unable to handle kernel paging request at virtual address ffff00006e3cd000 + ... + Call trace: + hns_roce_write_mtt+0x154/0x2f0 [hns_roce] + hns_roce_buf_write_mtt+0xa8/0xd8 [hns_roce] + hns_roce_create_srq+0x74c/0x808 [hns_roce] + ib_create_srq+0x28/0xc8 + +Fixes: 0203b14c4f32 ("RDMA/hns: Unify the calculation for hem index in hip08") +Signed-off-by: chenglang +Signed-off-by: Lijun Ou +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hem.c | 6 ++++-- + drivers/infiniband/hw/hns/hns_roce_mr.c | 4 ++-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c +index 4cdbcafa59155..cae23364cfea9 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hem.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c +@@ -763,6 +763,8 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev, + idx_offset = (obj & (table->num_obj - 1)) % obj_per_chunk; + dma_offset = offset = idx_offset * table->obj_size; + } else { ++ u32 seg_size = 64; /* 8 bytes per BA and 8 BA per segment */ ++ + hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop); + /* mtt mhop */ + i = mhop.l0_idx; +@@ -774,8 +776,8 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev, + hem_idx = i; + + hem = table->hem[hem_idx]; +- dma_offset = offset = (obj & (table->num_obj - 1)) * +- table->obj_size % mhop.bt_chunk_size; ++ dma_offset = offset = (obj & (table->num_obj - 1)) * seg_size % ++ mhop.bt_chunk_size; + if (mhop.hop_num == 2) + dma_offset = offset = 0; + } +diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c +index ee5991bd4171c..dd4bb0ec6113b 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_mr.c ++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c +@@ -746,7 +746,6 @@ static int hns_roce_write_mtt_chunk(struct hns_roce_dev *hr_dev, + struct hns_roce_hem_table *table; + dma_addr_t dma_handle; + __le64 *mtts; +- u32 s = start_index * sizeof(u64); + u32 bt_page_size; + u32 i; + +@@ -780,7 +779,8 @@ static int hns_roce_write_mtt_chunk(struct hns_roce_dev *hr_dev, + return -EINVAL; + + mtts = hns_roce_table_find(hr_dev, table, +- mtt->first_seg + s / hr_dev->caps.mtt_entry_sz, ++ mtt->first_seg + ++ start_index / HNS_ROCE_MTT_ENTRY_PER_SEG, + &dma_handle); + if (!mtts) + return -ENOMEM; +-- +2.20.1 + diff --git a/queue-5.0/rdma-vmw_pvrdma-fix-memory-leak-on-pvrdma_pci_remove.patch b/queue-5.0/rdma-vmw_pvrdma-fix-memory-leak-on-pvrdma_pci_remove.patch new file mode 100644 index 00000000000..c1e5ded438f --- /dev/null +++ b/queue-5.0/rdma-vmw_pvrdma-fix-memory-leak-on-pvrdma_pci_remove.patch @@ -0,0 +1,34 @@ +From bafb26da5b36455233f65e692289bc6c034a78d2 Mon Sep 17 00:00:00 2001 +From: Kamal Heib +Date: Wed, 3 Apr 2019 16:52:54 +0300 +Subject: RDMA/vmw_pvrdma: Fix memory leak on pvrdma_pci_remove + +[ Upstream commit ea7a5c706fa49273cf6d1d9def053ecb50db2076 ] + +Make sure to free the DSR on pvrdma_pci_remove() to avoid the memory leak. + +Fixes: 29c8d9eba550 ("IB: Add vmw_pvrdma driver") +Signed-off-by: Kamal Heib +Acked-by: Adit Ranadive +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +index 39c37b6fd7159..76b8dda40eddd 100644 +--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c ++++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +@@ -1125,6 +1125,8 @@ static void pvrdma_pci_remove(struct pci_dev *pdev) + pvrdma_page_dir_cleanup(dev, &dev->cq_pdir); + pvrdma_page_dir_cleanup(dev, &dev->async_pdir); + pvrdma_free_slots(dev); ++ dma_free_coherent(&pdev->dev, sizeof(*dev->dsr), dev->dsr, ++ dev->dsrbase); + + iounmap(dev->regs); + kfree(dev->sgid_tbl); +-- +2.20.1 + diff --git a/queue-5.0/scsi-csiostor-fix-missing-data-copy-in-csio_scsi_err.patch b/queue-5.0/scsi-csiostor-fix-missing-data-copy-in-csio_scsi_err.patch new file mode 100644 index 00000000000..afd6f35ff99 --- /dev/null +++ b/queue-5.0/scsi-csiostor-fix-missing-data-copy-in-csio_scsi_err.patch @@ -0,0 +1,38 @@ +From 661254668c5e0bde8b62012010d6ed417e2055cc Mon Sep 17 00:00:00 2001 +From: Varun Prakash +Date: Fri, 5 Apr 2019 20:39:13 +0530 +Subject: scsi: csiostor: fix missing data copy in csio_scsi_err_handler() + +[ Upstream commit 5c2442fd78998af60e13aba506d103f7f43f8701 ] + +If scsi cmd sglist is not suitable for DDP then csiostor driver uses +preallocated buffers for DDP, because of this data copy is required from +DDP buffer to scsi cmd sglist before calling ->scsi_done(). + +Signed-off-by: Varun Prakash +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/csiostor/csio_scsi.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c +index bc5547a62c00c..c54c6cd504c41 100644 +--- a/drivers/scsi/csiostor/csio_scsi.c ++++ b/drivers/scsi/csiostor/csio_scsi.c +@@ -1713,8 +1713,11 @@ csio_scsi_err_handler(struct csio_hw *hw, struct csio_ioreq *req) + } + + out: +- if (req->nsge > 0) ++ if (req->nsge > 0) { + scsi_dma_unmap(cmnd); ++ if (req->dcopy && (host_status == DID_OK)) ++ host_status = csio_scsi_copy_to_sgl(hw, req); ++ } + + cmnd->result = (((host_status) << 16) | scsi_status); + cmnd->scsi_done(cmnd); +-- +2.20.1 + diff --git a/queue-5.0/series b/queue-5.0/series index d9e8fd541db..b5b03ff5db5 100644 --- a/queue-5.0/series +++ b/queue-5.0/series @@ -5,3 +5,68 @@ staging-greybus-power_supply-fix-prop-descriptor-request-size.patch staging-wilc1000-avoid-gfp_kernel-allocation-from-atomic-context.patch staging-most-cdev-fix-chrdev_region-leak-in-mod_exit.patch staging-most-sound-pass-correct-device-when-creating-a-sound-card.patch +asoc-tlv320aic3x-fix-reset-gpio-reference-counting.patch +asoc-hdmi-codec-fix-s-pdif-dai.patch +asoc-stm32-sai-fix-iec958-controls-indexation.patch +asoc-stm32-sai-fix-exposed-capabilities-in-spdif-mod.patch +asoc-stm32-sai-fix-race-condition-in-irq-handler.patch +asoc-soc-pcm-fix-a-codec-fixup-issue-in-tdm-case.patch +asoc-hdac_hda-use-correct-format-to-setup-hda-codec.patch +asoc-intel-skl-fix-a-simultaneous-playback-capture-i.patch +asoc-dpcm-prevent-snd_soc_dpcm-use-after-free.patch +asoc-nau8824-fix-the-issue-of-the-widget-with-prefix.patch +asoc-nau8810-fix-the-issue-of-widget-with-prefixed-n.patch +asoc-samsung-odroid-fix-clock-configuration-for-4410.patch +asoc-rt5682-check-jd-status-when-system-resume.patch +asoc-rt5682-fix-jack-type-detection-issue.patch +asoc-rt5682-recording-has-no-sound-after-booting.patch +asoc-wm_adsp-add-locking-to-wm_adsp2_bus_error.patch +clk-meson-gxbb-round-the-vdec-dividers-to-closest.patch +asoc-stm32-dfsdm-manage-multiple-prepare.patch +asoc-stm32-dfsdm-fix-debugfs-warnings-on-entry-creat.patch +asoc-cs4270-set-auto-increment-bit-for-register-writ.patch +asoc-dapm-fix-null-pointer-dereference-in-snd_soc_da.patch +drm-omap-hdmi4_cec-fix-cec-clock-handling-for-pm.patch +ib-hfi1-clear-the-iowait-pending-bits-when-qp-is-put.patch +ib-hfi1-eliminate-opcode-tests-on-mr-deref.patch +ib-hfi1-fix-the-allocation-of-rsm-table.patch +mips-kgdb-fix-kgdb-support-for-smp-platforms.patch +asoc-tlv320aic32x4-fix-common-pins.patch +drm-mediatek-fix-an-error-code-in-mtk_hdmi_dt_parse_.patch +perf-x86-intel-fix-handling-of-wakeup_events-for-mul.patch +perf-x86-intel-initialize-tfa-msr.patch +linux-kernel.h-use-parentheses-around-argument-in-u6.patch +iov_iter-fix-build-error-without-config_crypto.patch +xtensa-fix-initialization-of-pt_regs-syscall-in-star.patch +asoc-rockchip-pdm-fix-regmap_ops-hang-issue.patch +drm-amdkfd-add-picasso-pci-id.patch +drm-amdgpu-adjust-ib-test-timeout-for-xgmi-configura.patch +drm-amdgpu-amdgpu_device_recover_vram-always-failed-.patch +drm-amd-display-fix-cursor-black-issue.patch +asoc-cs35l35-disable-regulators-on-driver-removal.patch +objtool-add-rewind_stack_do_exit-to-the-noreturn-lis.patch +slab-fix-a-crash-by-reading-proc-slab_allocators.patch +drm-sun4i-tcon-top-fix-null-invalid-pointer-derefere.patch +virtio_pci-fix-a-null-pointer-reference-in-vp_del_vq.patch +rdma-vmw_pvrdma-fix-memory-leak-on-pvrdma_pci_remove.patch +rdma-hns-fix-bug-that-caused-srq-creation-to-fail.patch +keys-trusted-fix-wvarags-warning.patch +scsi-csiostor-fix-missing-data-copy-in-csio_scsi_err.patch +drm-mediatek-fix-possible-object-reference-leak.patch +drm-mediatek-fix-the-rate-and-divder-of-hdmi-phy-for.patch +drm-mediatek-make-implementation-of-recalc_rate-for-.patch +drm-mediatek-remove-flag-clk_set_rate_parent-for-mt2.patch +drm-mediatek-using-new-factor-for-tvdpll-for-mt2701-.patch +drm-mediatek-no-change-parent-rate-in-round_rate-for.patch +asoc-intel-kbl-fix-wrong-number-of-channels.patch +asoc-stm32-sai-fix-master-clock-management.patch +alsa-hda-fix-racy-display-power-access.patch +virtio-blk-limit-number-of-hw-queues-by-nr_cpu_ids.patch +blk-mq-introduce-blk_mq_complete_request_sync.patch +nvme-cancel-request-synchronously.patch +nvme-fc-correct-csn-initialization-and-increments-on.patch +nvmet-fix-discover-log-page-when-offsets-are-used.patch +platform-x86-pmc_atom-drop-__initconst-on-dmi-table.patch +nfsv4.1-fix-incorrect-return-value-in-copy_file_rang.patch +perf-core-fix-perf_event_disable_inatomic-race.patch +iommu-amd-set-exclusion-range-correctly.patch diff --git a/queue-5.0/slab-fix-a-crash-by-reading-proc-slab_allocators.patch b/queue-5.0/slab-fix-a-crash-by-reading-proc-slab_allocators.patch new file mode 100644 index 00000000000..87b175432e3 --- /dev/null +++ b/queue-5.0/slab-fix-a-crash-by-reading-proc-slab_allocators.patch @@ -0,0 +1,44 @@ +From 26dbb49dd6414012e56311cf7d5d0e9fa37d3d75 Mon Sep 17 00:00:00 2001 +From: Qian Cai +Date: Sat, 6 Apr 2019 18:59:01 -0400 +Subject: slab: fix a crash by reading /proc/slab_allocators + +[ Upstream commit fcf88917dd435c6a4cb2830cb086ee58605a1d85 ] + +The commit 510ded33e075 ("slab: implement slab_root_caches list") +changes the name of the list node within "struct kmem_cache" from "list" +to "root_caches_node", but leaks_show() still use the "list" which +causes a crash when reading /proc/slab_allocators. + +You need to have CONFIG_SLAB=y and CONFIG_MEMCG=y to see the problem, +because without MEMCG all slab caches are root caches, and the "list" +node happens to be the right one. + +Fixes: 510ded33e075 ("slab: implement slab_root_caches list") +Signed-off-by: Qian Cai +Reviewed-by: Tobin C. Harding +Cc: Tejun Heo +Cc: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + mm/slab.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/mm/slab.c b/mm/slab.c +index 2f2aa8eaf7d98..188c4b65255dc 100644 +--- a/mm/slab.c ++++ b/mm/slab.c +@@ -4297,7 +4297,8 @@ static void show_symbol(struct seq_file *m, unsigned long address) + + static int leaks_show(struct seq_file *m, void *p) + { +- struct kmem_cache *cachep = list_entry(p, struct kmem_cache, list); ++ struct kmem_cache *cachep = list_entry(p, struct kmem_cache, ++ root_caches_node); + struct page *page; + struct kmem_cache_node *n; + const char *name; +-- +2.20.1 + diff --git a/queue-5.0/virtio-blk-limit-number-of-hw-queues-by-nr_cpu_ids.patch b/queue-5.0/virtio-blk-limit-number-of-hw-queues-by-nr_cpu_ids.patch new file mode 100644 index 00000000000..6537dd2d028 --- /dev/null +++ b/queue-5.0/virtio-blk-limit-number-of-hw-queues-by-nr_cpu_ids.patch @@ -0,0 +1,44 @@ +From d8cbe82796d5b7621095dbdf0cbbcd9a56c54808 Mon Sep 17 00:00:00 2001 +From: Dongli Zhang +Date: Wed, 27 Mar 2019 18:36:34 +0800 +Subject: virtio-blk: limit number of hw queues by nr_cpu_ids + +[ Upstream commit bf348f9b78d413e75bb079462751a1d86b6de36c ] + +When tag_set->nr_maps is 1, the block layer limits the number of hw queues +by nr_cpu_ids. No matter how many hw queues are used by virtio-blk, as it +has (tag_set->nr_maps == 1), it can use at most nr_cpu_ids hw queues. + +In addition, specifically for pci scenario, when the 'num-queues' specified +by qemu is more than maxcpus, virtio-blk would not be able to allocate more +than maxcpus vectors in order to have a vector for each queue. As a result, +it falls back into MSI-X with one vector for config and one shared for +queues. + +Considering above reasons, this patch limits the number of hw queues used +by virtio-blk by nr_cpu_ids. + +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Dongli Zhang +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/virtio_blk.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index b16a887bbd02a..29bede887237f 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -513,6 +513,8 @@ static int init_vq(struct virtio_blk *vblk) + if (err) + num_vqs = 1; + ++ num_vqs = min_t(unsigned int, nr_cpu_ids, num_vqs); ++ + vblk->vqs = kmalloc_array(num_vqs, sizeof(*vblk->vqs), GFP_KERNEL); + if (!vblk->vqs) + return -ENOMEM; +-- +2.20.1 + diff --git a/queue-5.0/virtio_pci-fix-a-null-pointer-reference-in-vp_del_vq.patch b/queue-5.0/virtio_pci-fix-a-null-pointer-reference-in-vp_del_vq.patch new file mode 100644 index 00000000000..fbfc1ef8104 --- /dev/null +++ b/queue-5.0/virtio_pci-fix-a-null-pointer-reference-in-vp_del_vq.patch @@ -0,0 +1,68 @@ +From 685da22e280eae8337b819b7c744aaad28e16f2e Mon Sep 17 00:00:00 2001 +From: Longpeng +Date: Sat, 9 Mar 2019 15:17:40 +0800 +Subject: virtio_pci: fix a NULL pointer reference in vp_del_vqs + +[ Upstream commit 6a8aae68c87349dbbcd46eac380bc43cdb98a13b ] + +If the msix_affinity_masks is alloced failed, then we'll +try to free some resources in vp_free_vectors() that may +access it directly. + +We met the following stack in our production: +[ 29.296767] BUG: unable to handle kernel NULL pointer dereference at (null) +[ 29.311151] IP: [] vp_free_vectors+0x6a/0x150 [virtio_pci] +[ 29.324787] PGD 0 +[ 29.333224] Oops: 0000 [#1] SMP +[...] +[ 29.425175] RIP: 0010:[] [] vp_free_vectors+0x6a/0x150 [virtio_pci] +[ 29.441405] RSP: 0018:ffff9a55c2dcfa10 EFLAGS: 00010206 +[ 29.453491] RAX: 0000000000000000 RBX: ffff9a55c322c400 RCX: 0000000000000000 +[ 29.467488] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff9a55c322c400 +[ 29.481461] RBP: ffff9a55c2dcfa20 R08: 0000000000000000 R09: ffffc1b6806ff020 +[ 29.495427] R10: 0000000000000e95 R11: 0000000000aaaaaa R12: 0000000000000000 +[ 29.509414] R13: 0000000000010000 R14: ffff9a55bd2d9e98 R15: ffff9a55c322c400 +[ 29.523407] FS: 00007fdcba69f8c0(0000) GS:ffff9a55c2840000(0000) knlGS:0000000000000000 +[ 29.538472] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 29.551621] CR2: 0000000000000000 CR3: 000000003ce52000 CR4: 00000000003607a0 +[ 29.565886] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 29.580055] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[ 29.594122] Call Trace: +[ 29.603446] [] vp_request_msix_vectors+0xe2/0x260 [virtio_pci] +[ 29.618017] [] vp_try_to_find_vqs+0x95/0x3b0 [virtio_pci] +[ 29.632152] [] vp_find_vqs+0x37/0xb0 [virtio_pci] +[ 29.645582] [] init_vq+0x153/0x260 [virtio_blk] +[ 29.658831] [] virtblk_probe+0xe8/0x87f [virtio_blk] +[...] + +Cc: Gonglei +Signed-off-by: Longpeng +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Gonglei +Signed-off-by: Sasha Levin +--- + drivers/virtio/virtio_pci_common.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c +index d0584c040c60f..7a0398bb84f77 100644 +--- a/drivers/virtio/virtio_pci_common.c ++++ b/drivers/virtio/virtio_pci_common.c +@@ -255,9 +255,11 @@ void vp_del_vqs(struct virtio_device *vdev) + for (i = 0; i < vp_dev->msix_used_vectors; ++i) + free_irq(pci_irq_vector(vp_dev->pci_dev, i), vp_dev); + +- for (i = 0; i < vp_dev->msix_vectors; i++) +- if (vp_dev->msix_affinity_masks[i]) +- free_cpumask_var(vp_dev->msix_affinity_masks[i]); ++ if (vp_dev->msix_affinity_masks) { ++ for (i = 0; i < vp_dev->msix_vectors; i++) ++ if (vp_dev->msix_affinity_masks[i]) ++ free_cpumask_var(vp_dev->msix_affinity_masks[i]); ++ } + + if (vp_dev->msix_enabled) { + /* Disable the vector used for configuration */ +-- +2.20.1 + diff --git a/queue-5.0/xtensa-fix-initialization-of-pt_regs-syscall-in-star.patch b/queue-5.0/xtensa-fix-initialization-of-pt_regs-syscall-in-star.patch new file mode 100644 index 00000000000..9daeb853e58 --- /dev/null +++ b/queue-5.0/xtensa-fix-initialization-of-pt_regs-syscall-in-star.patch @@ -0,0 +1,52 @@ +From ba13c3ffad200bbc92d212d84f7142cdca614cdf Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Wed, 3 Apr 2019 20:22:42 -0700 +Subject: xtensa: fix initialization of pt_regs::syscall in start_thread + +[ Upstream commit 2663147dc7465cb29040a05cc4286fdd839978b5 ] + +New pt_regs should indicate that there's no syscall, not that there's +syscall #0. While at it wrap macro body in do/while and parenthesize +macro arguments. + +Signed-off-by: Max Filippov +Signed-off-by: Sasha Levin +--- + arch/xtensa/include/asm/processor.h | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h +index f7dd895b2353e..0c14018d1c260 100644 +--- a/arch/xtensa/include/asm/processor.h ++++ b/arch/xtensa/include/asm/processor.h +@@ -187,15 +187,18 @@ struct thread_struct { + + /* Clearing a0 terminates the backtrace. */ + #define start_thread(regs, new_pc, new_sp) \ +- memset(regs, 0, sizeof(*regs)); \ +- regs->pc = new_pc; \ +- regs->ps = USER_PS_VALUE; \ +- regs->areg[1] = new_sp; \ +- regs->areg[0] = 0; \ +- regs->wmask = 1; \ +- regs->depc = 0; \ +- regs->windowbase = 0; \ +- regs->windowstart = 1; ++ do { \ ++ memset((regs), 0, sizeof(*(regs))); \ ++ (regs)->pc = (new_pc); \ ++ (regs)->ps = USER_PS_VALUE; \ ++ (regs)->areg[1] = (new_sp); \ ++ (regs)->areg[0] = 0; \ ++ (regs)->wmask = 1; \ ++ (regs)->depc = 0; \ ++ (regs)->windowbase = 0; \ ++ (regs)->windowstart = 1; \ ++ (regs)->syscall = NO_SYSCALL; \ ++ } while (0) + + /* Forward declaration */ + struct task_struct; +-- +2.20.1 +