--- /dev/null
+From e1a00b5b253a4f97216b9a33199a863987075162 Mon Sep 17 00:00:00 2001
+From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Date: Tue, 10 Sep 2019 22:51:52 +0900
+Subject: ALSA: firewire-tascam: check intermediate state of clock status and retry
+
+From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+
+commit e1a00b5b253a4f97216b9a33199a863987075162 upstream.
+
+2 bytes in MSB of register for clock status is zero during intermediate
+state after changing status of sampling clock in models of TASCAM FireWire
+series. The duration of this state differs depending on cases. During the
+state, it's better to retry reading the register for current status of
+the clock.
+
+In current implementation, the intermediate state is checked only when
+getting current sampling transmission frequency, then retry reading.
+This care is required for the other operations to read the register.
+
+This commit moves the codes of check and retry into helper function
+commonly used for operations to read the register.
+
+Fixes: e453df44f0d6 ("ALSA: firewire-tascam: add PCM functionality")
+Cc: <stable@vger.kernel.org> # v4.4+
+Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Link: https://lore.kernel.org/r/20190910135152.29800-3-o-takashi@sakamocchi.jp
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/firewire/tascam/tascam-stream.c | 42 ++++++++++++++++++++++------------
+ 1 file changed, 28 insertions(+), 14 deletions(-)
+
+--- a/sound/firewire/tascam/tascam-stream.c
++++ b/sound/firewire/tascam/tascam-stream.c
+@@ -9,20 +9,37 @@
+ #include <linux/delay.h>
+ #include "tascam.h"
+
++#define CLOCK_STATUS_MASK 0xffff0000
++#define CLOCK_CONFIG_MASK 0x0000ffff
++
+ #define CALLBACK_TIMEOUT 500
+
+ static int get_clock(struct snd_tscm *tscm, u32 *data)
+ {
++ int trial = 0;
+ __be32 reg;
+ int err;
+
+- err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST,
+- TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS,
+- ®, sizeof(reg), 0);
+- if (err >= 0)
++ while (trial++ < 5) {
++ err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST,
++ TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS,
++ ®, sizeof(reg), 0);
++ if (err < 0)
++ return err;
++
+ *data = be32_to_cpu(reg);
++ if (*data & CLOCK_STATUS_MASK)
++ break;
++
++ // In intermediate state after changing clock status.
++ msleep(50);
++ }
+
+- return err;
++ // Still in the intermediate state.
++ if (trial >= 5)
++ return -EAGAIN;
++
++ return 0;
+ }
+
+ static int set_clock(struct snd_tscm *tscm, unsigned int rate,
+@@ -35,7 +52,7 @@ static int set_clock(struct snd_tscm *ts
+ err = get_clock(tscm, &data);
+ if (err < 0)
+ return err;
+- data &= 0x0000ffff;
++ data &= CLOCK_CONFIG_MASK;
+
+ if (rate > 0) {
+ data &= 0x000000ff;
+@@ -80,17 +97,14 @@ static int set_clock(struct snd_tscm *ts
+
+ int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate)
+ {
+- u32 data = 0x0;
+- unsigned int trials = 0;
++ u32 data;
+ int err;
+
+- while (data == 0x0 || trials++ < 5) {
+- err = get_clock(tscm, &data);
+- if (err < 0)
+- return err;
++ err = get_clock(tscm, &data);
++ if (err < 0)
++ return err;
+
+- data = (data & 0xff000000) >> 24;
+- }
++ data = (data & 0xff000000) >> 24;
+
+ /* Check base rate. */
+ if ((data & 0x0f) == 0x01)
--- /dev/null
+From 2617120f4de6d0423384e0e86b14c78b9de84d5a Mon Sep 17 00:00:00 2001
+From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Date: Tue, 10 Sep 2019 22:51:51 +0900
+Subject: ALSA: firewire-tascam: handle error code when getting current source of clock
+
+From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+
+commit 2617120f4de6d0423384e0e86b14c78b9de84d5a upstream.
+
+The return value of snd_tscm_stream_get_clock() is ignored. This commit
+checks the value and handle error.
+
+Fixes: e453df44f0d6 ("ALSA: firewire-tascam: add PCM functionality")
+Cc: <stable@vger.kernel.org> # v4.4+
+Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Link: https://lore.kernel.org/r/20190910135152.29800-2-o-takashi@sakamocchi.jp
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/firewire/tascam/tascam-pcm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/sound/firewire/tascam/tascam-pcm.c
++++ b/sound/firewire/tascam/tascam-pcm.c
+@@ -81,6 +81,9 @@ static int pcm_open(struct snd_pcm_subst
+ goto err_locked;
+
+ err = snd_tscm_stream_get_clock(tscm, &clock);
++ if (err < 0)
++ goto err_locked;
++
+ if (clock != SND_TSCM_CLOCK_INTERNAL ||
+ amdtp_stream_pcm_running(&tscm->rx_stream) ||
+ amdtp_stream_pcm_running(&tscm->tx_stream)) {