--- /dev/null
+From c9fe573a6584034670c1a55ee8162d623519cbbf Mon Sep 17 00:00:00 2001
+From: "Hebbar, Gururaja" <gururaja.hebbar@ti.com>
+Date: Tue, 26 Jun 2012 19:25:11 +0530
+Subject: ASoC: tlv320aic3x: Fix codec pll configure bug
+
+From: "Hebbar, Gururaja" <gururaja.hebbar@ti.com>
+
+commit c9fe573a6584034670c1a55ee8162d623519cbbf upstream.
+
+In sound/soc/codecs/tlv320aic3x.c
+
+ data = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
+ snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
+ data | (pll_p << PLLP_SHIFT));
+
+In the above code, pll-p value is OR'ed with previous value without
+clearing it. Bug is not seen if pll-p value doesn't change across
+Sampling frequency.
+
+However on some platforms (like AM335x EVM-SK), pll-p may have different
+values across different sampling frequencies. In such case, above code
+configures the pll with a wrong value.
+Because of this bug, when a audio stream is played with pll value
+different from previous stream, audio is heard as differently(like its
+stretched).
+
+Signed-off-by: Hebbar, Gururaja <gururaja.hebbar@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/codecs/tlv320aic3x.c | 4 +---
+ sound/soc/codecs/tlv320aic3x.h | 1 +
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+--- a/sound/soc/codecs/tlv320aic3x.c
++++ b/sound/soc/codecs/tlv320aic3x.c
+@@ -936,9 +936,7 @@ static int aic3x_hw_params(struct snd_pc
+ }
+
+ found:
+- data = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
+- snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
+- data | (pll_p << PLLP_SHIFT));
++ snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p);
+ snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG,
+ pll_r << PLLR_SHIFT);
+ snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
+--- a/sound/soc/codecs/tlv320aic3x.h
++++ b/sound/soc/codecs/tlv320aic3x.h
+@@ -166,6 +166,7 @@
+
+ /* PLL registers bitfields */
+ #define PLLP_SHIFT 0
++#define PLLP_MASK 7
+ #define PLLQ_SHIFT 3
+ #define PLLR_SHIFT 0
+ #define PLLJ_SHIFT 2
--- /dev/null
+From b0dfa4541e48ac4cc5f017285432c89923ad0f58 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Wed, 20 Jun 2012 14:16:57 +0100
+Subject: ASoC: wm2200: Add missing BCLK rate
+
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+
+commit b0dfa4541e48ac4cc5f017285432c89923ad0f58 upstream.
+
+Without this very high BCLKs will be configured incorrectly.
+
+Reported-by: Axel Lin <axel.lin@gmail.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/codecs/wm2200.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/soc/codecs/wm2200.c
++++ b/sound/soc/codecs/wm2200.c
+@@ -1491,6 +1491,7 @@ static int wm2200_bclk_rates_dat[WM2200_
+
+ static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = {
+ 5644800,
++ 3763200,
+ 2882400,
+ 1881600,
+ 1411200,
--- /dev/null
+From 7508b657967cf664b5aa0f6367d05016e7e3bc2a Mon Sep 17 00:00:00 2001
+From: Panayiotis Karabassis <panayk@gmail.com>
+Date: Tue, 26 Jun 2012 23:37:17 +0300
+Subject: ath9k: enable serialize_regmode for non-PCIE AR9287
+
+From: Panayiotis Karabassis <panayk@gmail.com>
+
+commit 7508b657967cf664b5aa0f6367d05016e7e3bc2a upstream.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=42903
+
+Based on the work of <fynivx@gmail.com>
+
+Signed-off-by: Panayiotis Karabassis <panayk@gmail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/hw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -558,7 +558,7 @@ static int __ath9k_hw_init(struct ath_hw
+
+ if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
+ if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
+- ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) &&
++ ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) &&
+ !ah->is_pciexpress)) {
+ ah->config.serialize_regmode =
+ SER_REG_MODE_ON;
--- /dev/null
+From 76591bea9714a58d8924154068c78d702eb2cb17 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Fri, 15 Jun 2012 03:04:52 +0200
+Subject: ath9k: fix a tx rate duration calculation bug
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit 76591bea9714a58d8924154068c78d702eb2cb17 upstream.
+
+The rate pointer variable for a rate series is used in a loop before it is
+initialized. This went unnoticed because it was used earlier for the RTS/CTS
+rate. This bug can lead to the wrong PHY type being passed to the
+duration calculation function.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/xmit.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -1001,13 +1001,13 @@ static void ath_buf_set_rate(struct ath_
+ }
+
+ /* legacy rates */
++ rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
+ if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
+ !(rate->flags & IEEE80211_RATE_ERP_G))
+ phy = WLAN_RC_PHY_CCK;
+ else
+ phy = WLAN_RC_PHY_OFDM;
+
+- rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
+ info->rates[i].Rate = rate->hw_value;
+ if (rate->hw_value_short) {
+ if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
--- /dev/null
+From 2031b4c2b4904f7448ab9e4bc6b9bf16e32709f5 Mon Sep 17 00:00:00 2001
+From: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+Date: Wed, 6 Jun 2012 10:33:10 +0530
+Subject: ath9k: Fix a WARNING on suspend/resume with IBSS
+
+From: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+
+commit 2031b4c2b4904f7448ab9e4bc6b9bf16e32709f5 upstream.
+
+this patch is dependent on the patch "cfg80211: fix interface
+combinations"
+
+In ath9k currently we have ADHOC interface as a single incompatible
+interface. when drv_add_interface is called during resume we got to
+consider number of vifs already present in addition to checking the
+drivers 'opmode' information about ADHOC. we incorrectly assume
+an ADHOC interface is already present. Then we may miss some driver
+specific data for the ADHOC interface after resume.
+
+The above mentioned checks can be removed from the driver,
+as the patch 'cfg80211: fix interface combinations' ensures that
+if an interface type is not advertised by the driver in any of the
+interface combinations(via ieee80211_iface_combination) then it shall
+be treated as a single incompatible interface. Fixes the following
+warning on suspend/resume with ibss interface.
+
+ ath: phy0: Cannot create ADHOC interface when other
+ interfaces already exist.
+ WARNING: at net/mac80211/driver-ops.h:12
+ ieee80211_reconfig+0x1882/0x1ca0 [mac80211]()
+ Hardware name: 2842RK1
+ wlan2: Failed check-sdata-in-driver check, flags: 0x0
+
+ Call Trace:
+ [<c01361b2>] warn_slowpath_common+0x72/0xa0
+ [<f8aaa7c2>] ? ieee80211_reconfig+0x1882/0x1ca0
+ [mac80211]
+ [<f8aaa7c2>] ? ieee80211_reconfig+0x1882/0x1ca0
+ [mac80211]
+ [<c0136283>] warn_slowpath_fmt+0x33/0x40
+ [<f8aaa7c2>] ieee80211_reconfig+0x1882/0x1ca0 [mac80211]
+ [<c06c1d1a>] ? mutex_lock_nested+0x23a/0x2f0
+ [<f8a95097>] ieee80211_resume+0x27/0x70 [mac80211]
+ [<fd177edf>] wiphy_resume+0x8f/0xa0 [cfg80211]
+
+Cc: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
+Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/main.c | 9 ---------
+ 1 file changed, 9 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1419,15 +1419,6 @@ static int ath9k_add_interface(struct ie
+ }
+ }
+
+- if ((ah->opmode == NL80211_IFTYPE_ADHOC) ||
+- ((vif->type == NL80211_IFTYPE_ADHOC) &&
+- sc->nvifs > 0)) {
+- ath_err(common, "Cannot create ADHOC interface when other"
+- " interfaces already exist.\n");
+- ret = -EINVAL;
+- goto out;
+- }
+-
+ ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
+
+ sc->nvifs++;
--- /dev/null
+From bed3d9c0b71f9afbfec905cb6db3b9f16be29d4d Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sat, 23 Jun 2012 19:23:31 +0200
+Subject: ath9k: fix dynamic WEP related regression
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit bed3d9c0b71f9afbfec905cb6db3b9f16be29d4d upstream.
+
+commit 7a532fe7131216a02c81a6c1b1f8632da1195a58
+ath9k_hw: fix interpretation of the rx KeyMiss flag
+
+This commit used the rx key miss indication to detect packets that were
+passed from the hardware without being decrypted, however it seems that
+this bit is not only undefined in the static WEP case, but also for
+dynamically allocated WEP keys. This caused a regression when using
+WEP-LEAP.
+
+This patch fixes the regression by keeping track of which key indexes
+refer to CCMP keys and only using the key miss indication for those.
+
+Reported-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath.h | 1 +
+ drivers/net/wireless/ath/ath9k/recv.c | 3 ++-
+ drivers/net/wireless/ath/key.c | 4 ++++
+ 3 files changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath.h
++++ b/drivers/net/wireless/ath/ath.h
+@@ -143,6 +143,7 @@ struct ath_common {
+ u32 keymax;
+ DECLARE_BITMAP(keymap, ATH_KEYMAX);
+ DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX);
++ DECLARE_BITMAP(ccmp_keymap, ATH_KEYMAX);
+ enum ath_crypt_caps crypt_caps;
+
+ unsigned int clockrate;
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -821,7 +821,8 @@ static bool ath9k_rx_accept(struct ath_c
+ * descriptor does contain a valid key index. This has been observed
+ * mostly with CCMP encryption.
+ */
+- if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID)
++ if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID ||
++ !test_bit(rx_stats->rs_keyix, common->ccmp_keymap))
+ rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
+
+ if (!rx_stats->rs_datalen)
+--- a/drivers/net/wireless/ath/key.c
++++ b/drivers/net/wireless/ath/key.c
+@@ -556,6 +556,9 @@ int ath_key_config(struct ath_common *co
+ return -EIO;
+
+ set_bit(idx, common->keymap);
++ if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
++ set_bit(idx, common->ccmp_keymap);
++
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
+ set_bit(idx + 64, common->keymap);
+ set_bit(idx, common->tkip_keymap);
+@@ -582,6 +585,7 @@ void ath_key_delete(struct ath_common *c
+ return;
+
+ clear_bit(key->hw_key_idx, common->keymap);
++ clear_bit(key->hw_key_idx, common->ccmp_keymap);
+ if (key->cipher != WLAN_CIPHER_SUITE_TKIP)
+ return;
+
--- /dev/null
+From 80b08a8d8829a58b5db14b1417151094cc28face Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Fri, 15 Jun 2012 03:04:53 +0200
+Subject: ath9k: fix invalid pointer access in the tx path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit 80b08a8d8829a58b5db14b1417151094cc28face upstream.
+
+After setup_frame_info has been called, only info->control.rates is still
+valid, other control fields have been overwritten by the ath_frame_info
+data. Move the access to info->control.vif for checking short preamble
+to setup_frame_info before it gets overwritten.
+
+This regression was introduced in commit d47a61aa
+"ath9k: Fix multi-VIF BSS handling"
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Reported-by: Thomas Hühn <thomas@net.t-labs.tu-berlin.de>
+Acked-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
+ drivers/net/wireless/ath/ath9k/xmit.c | 29 +++++++++++++++++------------
+ 2 files changed, 18 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -213,6 +213,7 @@ struct ath_frame_info {
+ enum ath9k_key_type keytype;
+ u8 keyix;
+ u8 retries;
++ u8 rtscts_rate;
+ };
+
+ struct ath_buf_state {
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -938,6 +938,7 @@ static void ath_buf_set_rate(struct ath_
+ struct ieee80211_tx_rate *rates;
+ const struct ieee80211_rate *rate;
+ struct ieee80211_hdr *hdr;
++ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
+ int i;
+ u8 rix = 0;
+
+@@ -948,18 +949,7 @@ static void ath_buf_set_rate(struct ath_
+
+ /* set dur_update_en for l-sig computation except for PS-Poll frames */
+ info->dur_update = !ieee80211_is_pspoll(hdr->frame_control);
+-
+- /*
+- * We check if Short Preamble is needed for the CTS rate by
+- * checking the BSS's global flag.
+- * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
+- */
+- rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
+- info->rtscts_rate = rate->hw_value;
+-
+- if (tx_info->control.vif &&
+- tx_info->control.vif->bss_conf.use_short_preamble)
+- info->rtscts_rate |= rate->hw_value_short;
++ info->rtscts_rate = fi->rtscts_rate;
+
+ for (i = 0; i < 4; i++) {
+ bool is_40, is_sgi, is_sp;
+@@ -1776,10 +1766,22 @@ static void setup_frame_info(struct ieee
+ struct ieee80211_sta *sta = tx_info->control.sta;
+ struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
++ const struct ieee80211_rate *rate;
+ struct ath_frame_info *fi = get_frame_info(skb);
+ struct ath_node *an = NULL;
+ enum ath9k_key_type keytype;
++ bool short_preamble = false;
++
++ /*
++ * We check if Short Preamble is needed for the CTS rate by
++ * checking the BSS's global flag.
++ * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
++ */
++ if (tx_info->control.vif &&
++ tx_info->control.vif->bss_conf.use_short_preamble)
++ short_preamble = true;
+
++ rate = ieee80211_get_rts_cts_rate(hw, tx_info);
+ keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
+
+ if (sta)
+@@ -1794,6 +1796,9 @@ static void setup_frame_info(struct ieee
+ fi->keyix = ATH9K_TXKEYIX_INVALID;
+ fi->keytype = keytype;
+ fi->framelen = framelen;
++ fi->rtscts_rate = rate->hw_value;
++ if (short_preamble)
++ fi->rtscts_rate |= rate->hw_value_short;
+ }
+
+ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
--- /dev/null
+From bcb7ad7bcbef030e6ba71ede1f9866368aca7c99 Mon Sep 17 00:00:00 2001
+From: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+Date: Wed, 13 Jun 2012 21:28:09 +0530
+Subject: ath9k: Fix softlockup in AR9485
+
+From: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+
+commit bcb7ad7bcbef030e6ba71ede1f9866368aca7c99 upstream.
+
+steps to recreate:
+load latest ath9k driver with AR9485
+stop the network-manager and wpa_supplicant
+bring the interface up
+
+ Call Trace:
+ [<ffffffffa0517490>] ? ath_hw_check+0xe0/0xe0 [ath9k]
+ [<ffffffff812cd1e8>] __const_udelay+0x28/0x30
+ [<ffffffffa03bae7a>] ar9003_get_pll_sqsum_dvc+0x4a/0x80 [ath9k_hw]
+ [<ffffffffa05174eb>] ath_hw_pll_work+0x5b/0xe0 [ath9k]
+ [<ffffffff810744fe>] process_one_work+0x11e/0x470
+ [<ffffffff8107530f>] worker_thread+0x15f/0x360
+ [<ffffffff810751b0>] ? manage_workers+0x230/0x230
+ [<ffffffff81079af3>] kthread+0x93/0xa0
+ [<ffffffff815fd3a4>] kernel_thread_helper+0x4/0x10
+ [<ffffffff81079a60>] ? kthread_freezable_should_stop+0x70/0x70
+ [<ffffffff815fd3a0>] ? gs_change+0x13/0x13
+
+ensure that the PLL-WAR for AR9485/AR9340 is executed only if the STA is
+associated (or) IBSS/AP mode had started beaconing. Ideally this WAR
+is needed to recover from some rare beacon stuck during stress testing.
+Before the STA is associated/IBSS had started beaconing, PLL4(0x1618c)
+always seem to have zero even though we had configured PLL3(0x16188) to
+query about PLL's locking status. When we keep on polling infinitely PLL4's
+8th bit(ie check for PLL locking measurements is done), machine hangs
+due to softlockup.
+
+fixes https://bugzilla.redhat.com/show_bug.cgi?id=811142
+
+Reported-by: Rolf Offermanns <rolf.offermanns@gmx.net>
+Tested-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/main.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -960,6 +960,15 @@ void ath_hw_pll_work(struct work_struct
+ hw_pll_work.work);
+ u32 pll_sqsum;
+
++ /*
++ * ensure that the PLL WAR is executed only
++ * after the STA is associated (or) if the
++ * beaconing had started in interfaces that
++ * uses beacons.
++ */
++ if (!(sc->sc_flags & SC_OP_BEACONS))
++ return;
++
+ if (AR_SREV_9485(sc->sc_ah)) {
+
+ ath9k_ps_wakeup(sc);
--- /dev/null
+From 931cb03afed7b541392295f3afc4638da32f08a0 Mon Sep 17 00:00:00 2001
+From: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
+Date: Wed, 20 Jun 2012 16:29:20 +0530
+Subject: ath9k_htc: configure bssid on ASSOC/IBSS change
+
+From: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
+
+commit 931cb03afed7b541392295f3afc4638da32f08a0 upstream.
+
+After the change "mac80211: remove spurious BSSID change flag",
+BSS_CHANGED_BSSID will not be passed on association or IBSS
+status changes. So it could be better to program bssid on ASSOC
+or IBSS change notification. Not doing so, is affecting the
+packet transmission.
+
+Reported-by: Michael Leun <lkml20120218@newton.leun.net>
+Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+@@ -1496,6 +1496,7 @@ static void ath9k_htc_bss_info_changed(s
+ priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--;
+
+ if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
++ ath9k_htc_choose_set_bssid(priv);
+ if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1))
+ ath9k_htc_start_ani(priv);
+ else if (priv->num_sta_assoc_vif == 0)
+@@ -1503,13 +1504,11 @@ static void ath9k_htc_bss_info_changed(s
+ }
+ }
+
+- if (changed & BSS_CHANGED_BSSID) {
++ if (changed & BSS_CHANGED_IBSS) {
+ if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
+ common->curaid = bss_conf->aid;
+ memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+ ath9k_htc_set_bssid(priv);
+- } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
+- ath9k_htc_choose_set_bssid(priv);
+ }
+ }
+
--- /dev/null
+From f18e3c6b67f448ec47b3a5b242789bd3d5644879 Mon Sep 17 00:00:00 2001
+From: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+Date: Mon, 18 Jun 2012 13:13:30 +0530
+Subject: ath9k_hw: avoid possible infinite loop in
+ ar9003_get_pll_sqsum_dvc
+
+From: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+
+commit f18e3c6b67f448ec47b3a5b242789bd3d5644879 upstream.
+
+"ath9k: Fix softlockup in AR9485" with commit id
+64bc1239c790e051ff677e023435d770d2ffa174 fixed the reported
+issue, yet its better to avoid the possible infinite loop
+in ar9003_get_pll_sqsum_dvc by having a timeout as suggested
+by ath9k maintainers.
+http://www.spinics.net/lists/linux-wireless/msg92126.html.
+Based on my testing PLL's locking measurement is done in
+~200us (2 iterations).
+
+Cc: Rolf Offermanns <rolf.offermanns@gmx.net>
+Cc: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+Cc: Senthil Balasubramanian <senthilb@qca.qualcomm.com>
+Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/hw.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -720,13 +720,25 @@ static void ath9k_hw_init_qos(struct ath
+
+ u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
+ {
++ struct ath_common *common = ath9k_hw_common(ah);
++ int i = 0;
++
+ REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
+ udelay(100);
+ REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
+
+- while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0)
++ while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) {
++
+ udelay(100);
+
++ if (WARN_ON_ONCE(i >= 100)) {
++ ath_err(common, "PLL4 meaurement not done\n");
++ break;
++ }
++
++ i++;
++ }
++
+ return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3;
+ }
+ EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
--- /dev/null
+From e73f843a3235a19de38359c91586e9eadef12238 Mon Sep 17 00:00:00 2001
+From: Suresh Jayaraman <sjayaraman@suse.com>
+Date: Tue, 12 Jun 2012 07:15:50 +0530
+Subject: cifs: fix parsing of password mount option
+
+From: Suresh Jayaraman <sjayaraman@suse.com>
+
+commit e73f843a3235a19de38359c91586e9eadef12238 upstream.
+
+The double delimiter check that allows a comma in the password parsing code is
+unconditional. We set "tmp_end" to the end of the string and we continue to
+check for double delimiter. In the case where the password doesn't contain a
+comma we end up setting tmp_end to NULL and eventually setting "options" to
+"end". This results in the premature termination of the options string and hence
+the values of UNCip and UNC are being set to NULL. This results in mount failure
+with "Connecting to DFS root not implemented yet" error.
+
+This error is usually not noticable as we have password as the last option in
+the superblock mountdata. But when we call expand_dfs_referral() from
+cifs_mount() and try to compose mount options for the submount, the resulting
+mountdata will be of the form
+
+ ",ver=1,user=foo,pass=bar,ip=x.x.x.x,unc=\\server\share"
+
+and hence results in the above error. This bug has been seen with older NAS
+servers running Samba 3.0.24.
+
+Fix this by moving the double delimiter check inside the conditional loop.
+
+Changes since -v1
+
+ - removed the wrong strlen() micro optimization.
+
+Signed-off-by: Suresh Jayaraman <sjayaraman@suse.com>
+Acked-by: Sachin Prabhu <sprabhu@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/connect.c | 32 +++++++++++++++++---------------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1585,24 +1585,26 @@ cifs_parse_mount_options(const char *mou
+ * If yes, we have encountered a double deliminator
+ * reset the NULL character to the deliminator
+ */
+- if (tmp_end < end && tmp_end[1] == delim)
++ if (tmp_end < end && tmp_end[1] == delim) {
+ tmp_end[0] = delim;
+
+- /* Keep iterating until we get to a single deliminator
+- * OR the end
+- */
+- while ((tmp_end = strchr(tmp_end, delim)) != NULL &&
+- (tmp_end[1] == delim)) {
+- tmp_end = (char *) &tmp_end[2];
+- }
++ /* Keep iterating until we get to a single
++ * deliminator OR the end
++ */
++ while ((tmp_end = strchr(tmp_end, delim))
++ != NULL && (tmp_end[1] == delim)) {
++ tmp_end = (char *) &tmp_end[2];
++ }
+
+- /* Reset var options to point to next element */
+- if (tmp_end) {
+- tmp_end[0] = '\0';
+- options = (char *) &tmp_end[1];
+- } else
+- /* Reached the end of the mount option string */
+- options = end;
++ /* Reset var options to point to next element */
++ if (tmp_end) {
++ tmp_end[0] = '\0';
++ options = (char *) &tmp_end[1];
++ } else
++ /* Reached the end of the mount option
++ * string */
++ options = end;
++ }
+
+ /* Now build new password string */
+ temp_len = strlen(value);
--- /dev/null
+From ec01d738a1691dfc85b96b9f796020267a7be577 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Mon, 2 Jul 2012 07:24:25 -0400
+Subject: cifs: when server doesn't set CAP_LARGE_READ_X, cap default rsize at MaxBufferSize
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit ec01d738a1691dfc85b96b9f796020267a7be577 upstream.
+
+When the server doesn't advertise CAP_LARGE_READ_X, then MS-CIFS states
+that you must cap the size of the read at the client's MaxBufferSize.
+Unfortunately, testing with many older servers shows that they often
+can't service a read larger than their own MaxBufferSize.
+
+Since we can't assume what the server will do in this situation, we must
+be conservative here for the default. When the server can't do large
+reads, then assume that it can't satisfy any read larger than its
+MaxBufferSize either.
+
+Luckily almost all modern servers can do large reads, so this won't
+affect them. This is really just for older win9x and OS/2 era servers.
+Also, note that this patch just governs the default rsize. The admin can
+always override this if he so chooses.
+
+Reported-by: David H. Durgee <dhdurgee@acm.org>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steven French <sfrench@w500smf.(none)>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/connect.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -3398,18 +3398,15 @@ cifs_negotiate_rsize(struct cifs_tcon *t
+ * MS-CIFS indicates that servers are only limited by the client's
+ * bufsize for reads, testing against win98se shows that it throws
+ * INVALID_PARAMETER errors if you try to request too large a read.
++ * OS/2 just sends back short reads.
+ *
+- * If the server advertises a MaxBufferSize of less than one page,
+- * assume that it also can't satisfy reads larger than that either.
+- *
+- * FIXME: Is there a better heuristic for this?
++ * If the server doesn't advertise CAP_LARGE_READ_X, then assume that
++ * it can't handle a read request larger than its MaxBufferSize either.
+ */
+ if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP))
+ defsize = CIFS_DEFAULT_IOSIZE;
+ else if (server->capabilities & CAP_LARGE_READ_X)
+ defsize = CIFS_DEFAULT_NON_POSIX_RSIZE;
+- else if (server->maxBuf >= PAGE_CACHE_SIZE)
+- defsize = CIFSMaxBufSize;
+ else
+ defsize = server->maxBuf - sizeof(READ_RSP);
+
--- /dev/null
+From f2f12b6fc032c7b1419fd6db84e2868b5f05a878 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <shuah.khan@hp.com>
+Date: Wed, 6 Jun 2012 10:50:06 -0600
+Subject: iommu/amd: Fix missing iommu_shutdown initialization in passthrough mode
+
+From: Shuah Khan <shuah.khan@hp.com>
+
+commit f2f12b6fc032c7b1419fd6db84e2868b5f05a878 upstream.
+
+The iommu_shutdown callback is not initialized when the AMD
+IOMMU driver runs in passthrough mode. Fix that by moving
+the callback initialization before the check for
+passthrough mode.
+
+Signed-off-by: Shuah Khan <shuah.khan@hp.com>
+Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/amd_iommu_init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/iommu/amd_iommu_init.c
++++ b/drivers/iommu/amd_iommu_init.c
+@@ -1641,6 +1641,8 @@ static int __init amd_iommu_init(void)
+
+ amd_iommu_init_api();
+
++ x86_platform.iommu_shutdown = disable_iommus;
++
+ if (iommu_pass_through)
+ goto out;
+
+@@ -1649,8 +1651,6 @@ static int __init amd_iommu_init(void)
+ else
+ printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n");
+
+- x86_platform.iommu_shutdown = disable_iommus;
+-
+ out:
+ return ret;
+
--- /dev/null
+From ac1534a55d1e87d59a21c09c570605933b551480 Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <joerg.roedel@amd.com>
+Date: Thu, 21 Jun 2012 14:52:40 +0200
+Subject: iommu/amd: Initialize dma_ops for hotplug and sriov devices
+
+From: Joerg Roedel <joerg.roedel@amd.com>
+
+commit ac1534a55d1e87d59a21c09c570605933b551480 upstream.
+
+When a device is added to the system at runtime the AMD
+IOMMU driver initializes the necessary data structures to
+handle translation for it. But it forgets to change the
+per-device dma_ops to point to the AMD IOMMU driver. So
+mapping actually never happens and all DMA accesses end in
+an IO_PAGE_FAULT. Fix this.
+
+Reported-by: Stefan Assmann <sassmann@redhat.com>
+Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/amd_iommu.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/iommu/amd_iommu.c
++++ b/drivers/iommu/amd_iommu.c
+@@ -83,6 +83,8 @@ static struct iommu_ops amd_iommu_ops;
+ static ATOMIC_NOTIFIER_HEAD(ppr_notifier);
+ int amd_iommu_max_glx_val = -1;
+
++static struct dma_map_ops amd_iommu_dma_ops;
++
+ /*
+ * general struct to manage commands send to an IOMMU
+ */
+@@ -2267,6 +2269,13 @@ static int device_change_notifier(struct
+ list_add_tail(&dma_domain->list, &iommu_pd_list);
+ spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
+
++ dev_data = get_dev_data(dev);
++
++ if (!dev_data->passthrough)
++ dev->archdata.dma_ops = &amd_iommu_dma_ops;
++ else
++ dev->archdata.dma_ops = &nommu_dma_ops;
++
+ break;
+ case BUS_NOTIFY_DEL_DEVICE:
+
--- /dev/null
+From 8f53dc724a83a0082184fa27df80c25c7df47340 Mon Sep 17 00:00:00 2001
+From: Hiroshi DOYU <hdoyu@nvidia.com>
+Date: Wed, 27 Jun 2012 12:54:01 +0300
+Subject: iommu/tegra: smmu: Fix unsleepable memory allocation
+
+From: Hiroshi DOYU <hdoyu@nvidia.com>
+
+commit 8f53dc724a83a0082184fa27df80c25c7df47340 upstream.
+
+allo_pdir() is called in smmu_iommu_domain_init() with spin_lock
+held. memory allocations in it have to be atomic/unsleepable.
+
+Signed-off-by: Hiroshi DOYU <hdoyu@nvidia.com>
+Reported-by: Chris Wright <chrisw@sous-sol.org>
+Acked-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/tegra-smmu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/iommu/tegra-smmu.c
++++ b/drivers/iommu/tegra-smmu.c
+@@ -550,13 +550,13 @@ static int alloc_pdir(struct smmu_as *as
+ return 0;
+
+ as->pte_count = devm_kzalloc(smmu->dev,
+- sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
++ sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_ATOMIC);
+ if (!as->pte_count) {
+ dev_err(smmu->dev,
+ "failed to allocate smmu_device PTE cunters\n");
+ return -ENOMEM;
+ }
+- as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA);
++ as->pdir_page = alloc_page(GFP_ATOMIC | __GFP_DMA);
+ if (!as->pdir_page) {
+ dev_err(smmu->dev,
+ "failed to allocate smmu_device page directory\n");
--- /dev/null
+From 5a081caa0414b9bbb82c17ffab9d6fe66edbb72f Mon Sep 17 00:00:00 2001
+From: Ohad Ben-Cohen <ohad@wizery.com>
+Date: Wed, 6 Jun 2012 10:09:25 +0300
+Subject: rpmsg: avoid premature deallocation of endpoints
+
+From: Ohad Ben-Cohen <ohad@wizery.com>
+
+commit 5a081caa0414b9bbb82c17ffab9d6fe66edbb72f upstream.
+
+When an inbound message arrives, the rpmsg core looks up its
+associated endpoint and invokes the registered callback.
+
+If a message arrives while its endpoint is being removed (because
+the rpmsg driver was removed, or a recovery of a remote processor
+has kicked in) we must ensure atomicity, i.e.:
+
+- Either the ept is removed before it is found
+
+or
+
+- The ept is found but will not be freed until the callback returns
+
+This is achieved by maintaining a per-ept reference count, which,
+when drops to zero, will trigger deallocation of the ept.
+
+With this in hand, it is now forbidden to directly deallocate
+epts once they have been added to the endpoints idr.
+
+Reported-by: Fernando Guzman Lugo <fernando.lugo@ti.com>
+Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rpmsg/virtio_rpmsg_bus.c | 36 ++++++++++++++++++++++++++++++++++--
+ include/linux/rpmsg.h | 3 +++
+ 2 files changed, 37 insertions(+), 2 deletions(-)
+
+--- a/drivers/rpmsg/virtio_rpmsg_bus.c
++++ b/drivers/rpmsg/virtio_rpmsg_bus.c
+@@ -188,6 +188,26 @@ static int rpmsg_uevent(struct device *d
+ rpdev->id.name);
+ }
+
++/**
++ * __ept_release() - deallocate an rpmsg endpoint
++ * @kref: the ept's reference count
++ *
++ * This function deallocates an ept, and is invoked when its @kref refcount
++ * drops to zero.
++ *
++ * Never invoke this function directly!
++ */
++static void __ept_release(struct kref *kref)
++{
++ struct rpmsg_endpoint *ept = container_of(kref, struct rpmsg_endpoint,
++ refcount);
++ /*
++ * At this point no one holds a reference to ept anymore,
++ * so we can directly free it
++ */
++ kfree(ept);
++}
++
+ /* for more info, see below documentation of rpmsg_create_ept() */
+ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp,
+ struct rpmsg_channel *rpdev, rpmsg_rx_cb_t cb,
+@@ -206,6 +226,8 @@ static struct rpmsg_endpoint *__rpmsg_cr
+ return NULL;
+ }
+
++ kref_init(&ept->refcount);
++
+ ept->rpdev = rpdev;
+ ept->cb = cb;
+ ept->priv = priv;
+@@ -238,7 +260,7 @@ rem_idr:
+ idr_remove(&vrp->endpoints, request);
+ free_ept:
+ mutex_unlock(&vrp->endpoints_lock);
+- kfree(ept);
++ kref_put(&ept->refcount, __ept_release);
+ return NULL;
+ }
+
+@@ -306,7 +328,7 @@ __rpmsg_destroy_ept(struct virtproc_info
+ idr_remove(&vrp->endpoints, ept->addr);
+ mutex_unlock(&vrp->endpoints_lock);
+
+- kfree(ept);
++ kref_put(&ept->refcount, __ept_release);
+ }
+
+ /**
+@@ -790,7 +812,13 @@ static void rpmsg_recv_done(struct virtq
+
+ /* use the dst addr to fetch the callback of the appropriate user */
+ mutex_lock(&vrp->endpoints_lock);
++
+ ept = idr_find(&vrp->endpoints, msg->dst);
++
++ /* let's make sure no one deallocates ept while we use it */
++ if (ept)
++ kref_get(&ept->refcount);
++
+ mutex_unlock(&vrp->endpoints_lock);
+
+ if (ept && ept->cb)
+@@ -798,6 +826,10 @@ static void rpmsg_recv_done(struct virtq
+ else
+ dev_warn(dev, "msg received with no recepient\n");
+
++ /* farewell, ept, we don't need you anymore */
++ if (ept)
++ kref_put(&ept->refcount, __ept_release);
++
+ /* publish the real size of the buffer */
+ sg_init_one(&sg, msg, RPMSG_BUF_SIZE);
+
+--- a/include/linux/rpmsg.h
++++ b/include/linux/rpmsg.h
+@@ -38,6 +38,7 @@
+ #include <linux/types.h>
+ #include <linux/device.h>
+ #include <linux/mod_devicetable.h>
++#include <linux/kref.h>
+
+ /* The feature bitmap for virtio rpmsg */
+ #define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */
+@@ -120,6 +121,7 @@ typedef void (*rpmsg_rx_cb_t)(struct rpm
+ /**
+ * struct rpmsg_endpoint - binds a local rpmsg address to its user
+ * @rpdev: rpmsg channel device
++ * @refcount: when this drops to zero, the ept is deallocated
+ * @cb: rx callback handler
+ * @addr: local rpmsg address
+ * @priv: private data for the driver's use
+@@ -140,6 +142,7 @@ typedef void (*rpmsg_rx_cb_t)(struct rpm
+ */
+ struct rpmsg_endpoint {
+ struct rpmsg_channel *rpdev;
++ struct kref refcount;
+ rpmsg_rx_cb_t cb;
+ u32 addr;
+ void *priv;
--- /dev/null
+From 15fd943af50dbc5f7f4de33835795c72595f7bf4 Mon Sep 17 00:00:00 2001
+From: Ohad Ben-Cohen <ohad@wizery.com>
+Date: Thu, 7 Jun 2012 15:39:35 +0300
+Subject: rpmsg: make sure inflight messages don't invoke just-removed callbacks
+
+From: Ohad Ben-Cohen <ohad@wizery.com>
+
+commit 15fd943af50dbc5f7f4de33835795c72595f7bf4 upstream.
+
+When inbound messages arrive, rpmsg core looks up their associated
+endpoint (by destination address) and then invokes their callback.
+
+We've made sure that endpoints will never be de-allocated after they
+were found by rpmsg core, but we also need to protect against the
+(rare) scenario where the rpmsg driver was just removed, and its
+callback function isn't available anymore.
+
+This is achieved by introducing a callback mutex, which must be taken
+before the callback is invoked, and, obviously, before it is removed.
+
+Reported-by: Fernando Guzman Lugo <fernando.lugo@ti.com>
+Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rpmsg/virtio_rpmsg_bus.c | 25 +++++++++++++++++++------
+ include/linux/rpmsg.h | 3 +++
+ 2 files changed, 22 insertions(+), 6 deletions(-)
+
+--- a/drivers/rpmsg/virtio_rpmsg_bus.c
++++ b/drivers/rpmsg/virtio_rpmsg_bus.c
+@@ -227,6 +227,7 @@ static struct rpmsg_endpoint *__rpmsg_cr
+ }
+
+ kref_init(&ept->refcount);
++ mutex_init(&ept->cb_lock);
+
+ ept->rpdev = rpdev;
+ ept->cb = cb;
+@@ -324,10 +325,16 @@ EXPORT_SYMBOL(rpmsg_create_ept);
+ static void
+ __rpmsg_destroy_ept(struct virtproc_info *vrp, struct rpmsg_endpoint *ept)
+ {
++ /* make sure new inbound messages can't find this ept anymore */
+ mutex_lock(&vrp->endpoints_lock);
+ idr_remove(&vrp->endpoints, ept->addr);
+ mutex_unlock(&vrp->endpoints_lock);
+
++ /* make sure in-flight inbound messages won't invoke cb anymore */
++ mutex_lock(&ept->cb_lock);
++ ept->cb = NULL;
++ mutex_unlock(&ept->cb_lock);
++
+ kref_put(&ept->refcount, __ept_release);
+ }
+
+@@ -821,14 +828,20 @@ static void rpmsg_recv_done(struct virtq
+
+ mutex_unlock(&vrp->endpoints_lock);
+
+- if (ept && ept->cb)
+- ept->cb(ept->rpdev, msg->data, msg->len, ept->priv, msg->src);
+- else
+- dev_warn(dev, "msg received with no recepient\n");
++ if (ept) {
++ /* make sure ept->cb doesn't go away while we use it */
++ mutex_lock(&ept->cb_lock);
+
+- /* farewell, ept, we don't need you anymore */
+- if (ept)
++ if (ept->cb)
++ ept->cb(ept->rpdev, msg->data, msg->len, ept->priv,
++ msg->src);
++
++ mutex_unlock(&ept->cb_lock);
++
++ /* farewell, ept, we don't need you anymore */
+ kref_put(&ept->refcount, __ept_release);
++ } else
++ dev_warn(dev, "msg received with no recepient\n");
+
+ /* publish the real size of the buffer */
+ sg_init_one(&sg, msg, RPMSG_BUF_SIZE);
+--- a/include/linux/rpmsg.h
++++ b/include/linux/rpmsg.h
+@@ -39,6 +39,7 @@
+ #include <linux/device.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/kref.h>
++#include <linux/mutex.h>
+
+ /* The feature bitmap for virtio rpmsg */
+ #define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */
+@@ -123,6 +124,7 @@ typedef void (*rpmsg_rx_cb_t)(struct rpm
+ * @rpdev: rpmsg channel device
+ * @refcount: when this drops to zero, the ept is deallocated
+ * @cb: rx callback handler
++ * @cb_lock: must be taken before accessing/changing @cb
+ * @addr: local rpmsg address
+ * @priv: private data for the driver's use
+ *
+@@ -144,6 +146,7 @@ struct rpmsg_endpoint {
+ struct rpmsg_channel *rpdev;
+ struct kref refcount;
+ rpmsg_rx_cb_t cb;
++ struct mutex cb_lock;
+ u32 addr;
+ void *priv;
+ };
udf-use-ret-instead-of-abusing-i-in-udf_load_logicalvol.patch
udf-avoid-run-away-loop-when-partition-table-length-is-corrupted.patch
udf-fortify-loading-of-sparing-table.patch
+iommu-amd-fix-missing-iommu_shutdown-initialization-in-passthrough-mode.patch
+iommu-amd-initialize-dma_ops-for-hotplug-and-sriov-devices.patch
+iommu-tegra-smmu-fix-unsleepable-memory-allocation.patch
+rpmsg-avoid-premature-deallocation-of-endpoints.patch
+rpmsg-make-sure-inflight-messages-don-t-invoke-just-removed-callbacks.patch
+cifs-fix-parsing-of-password-mount-option.patch
+cifs-when-server-doesn-t-set-cap_large_read_x-cap-default-rsize-at-maxbuffersize.patch
+ath9k-fix-a-warning-on-suspend-resume-with-ibss.patch
+ath9k-fix-softlockup-in-ar9485.patch
+ath9k-fix-a-tx-rate-duration-calculation-bug.patch
+ath9k-fix-invalid-pointer-access-in-the-tx-path.patch
+ath9k_hw-avoid-possible-infinite-loop-in.patch
+ath9k_htc-configure-bssid-on-assoc-ibss-change.patch
+ath9k-fix-dynamic-wep-related-regression.patch
+ath9k-enable-serialize_regmode-for-non-pcie-ar9287.patch
+asoc-wm2200-add-missing-bclk-rate.patch
+asoc-tlv320aic3x-fix-codec-pll-configure-bug.patch