From: Greg Kroah-Hartman Date: Sat, 5 Mar 2016 21:10:48 +0000 (-0800) Subject: 4.4-stable patches X-Git-Tag: v3.10.100~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c9202962615d69d7bad90e5cc7d8fe47435ba56e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: adv7604-fix-tx-5v-detect-regression.patch alsa-ctl-fix-ioctls-for-x32-abi.patch alsa-hda-fix-mic-issues-on-acer-aspire-e1-472.patch alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch alsa-hdspm-fix-zero-division.patch alsa-pcm-fix-ioctls-for-x32-abi.patch alsa-rawmidi-fix-ioctls-x32-abi.patch alsa-seq-oss-don-t-drain-at-closing-a-client.patch alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch alsa-timer-fix-ioctls-for-x32-abi.patch alsa-usb-audio-add-a-quirk-for-plantronics-da45.patch dmaengine-pxa_dma-fix-cyclic-transfers.patch --- diff --git a/queue-4.4/adv7604-fix-tx-5v-detect-regression.patch b/queue-4.4/adv7604-fix-tx-5v-detect-regression.patch new file mode 100644 index 00000000000..f9fc797e454 --- /dev/null +++ b/queue-4.4/adv7604-fix-tx-5v-detect-regression.patch @@ -0,0 +1,36 @@ +From 0ba4581c84cfb39fd527f6b3457f1c97f6356c04 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Wed, 10 Feb 2016 08:09:10 -0200 +Subject: [media] adv7604: fix tx 5v detect regression + +From: Hans Verkuil + +commit 0ba4581c84cfb39fd527f6b3457f1c97f6356c04 upstream. + +The 5 volt detect functionality broke in 3.14: the code reads IO register 0x70 +again after it has already been cleared. Instead it should use the cached +irq_reg_0x70 value and the io_write to 0x71 to clear 0x70 can be dropped since +this has already been done. + +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/i2c/adv7604.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/media/i2c/adv7604.c ++++ b/drivers/media/i2c/adv7604.c +@@ -1960,10 +1960,9 @@ static int adv76xx_isr(struct v4l2_subde + } + + /* tx 5v detect */ +- tx_5v = io_read(sd, 0x70) & info->cable_det_mask; ++ tx_5v = irq_reg_0x70 & info->cable_det_mask; + if (tx_5v) { + v4l2_dbg(1, debug, sd, "%s: tx_5v: 0x%x\n", __func__, tx_5v); +- io_write(sd, 0x71, tx_5v); + adv76xx_s_detect_tx_5v_ctrl(sd); + if (handled) + *handled = true; diff --git a/queue-4.4/alsa-ctl-fix-ioctls-for-x32-abi.patch b/queue-4.4/alsa-ctl-fix-ioctls-for-x32-abi.patch new file mode 100644 index 00000000000..598c2454fb6 --- /dev/null +++ b/queue-4.4/alsa-ctl-fix-ioctls-for-x32-abi.patch @@ -0,0 +1,225 @@ +From 6236d8bb2afcfe71b88ecea554e0dc638090a45f Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sat, 27 Feb 2016 17:52:42 +0100 +Subject: ALSA: ctl: Fix ioctls for X32 ABI + +From: Takashi Iwai + +commit 6236d8bb2afcfe71b88ecea554e0dc638090a45f upstream. + +The X32 ABI takes the same alignment like x86-64, and this may result +in the incompatible struct size from ia32. Unfortunately, we hit this +in some control ABI: struct snd_ctl_elem_value differs between them +due to the position of 64bit variable array. This ends up with the +unknown ioctl (ENOTTY) error. + +The fix is to add the compat entries for the new aligned struct. + +Reported-and-tested-by: Steven Newbury +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/control_compat.c | 90 ++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 74 insertions(+), 16 deletions(-) + +--- a/sound/core/control_compat.c ++++ b/sound/core/control_compat.c +@@ -170,6 +170,19 @@ struct snd_ctl_elem_value32 { + unsigned char reserved[128]; + }; + ++#ifdef CONFIG_X86_X32 ++/* x32 has a different alignment for 64bit values from ia32 */ ++struct snd_ctl_elem_value_x32 { ++ struct snd_ctl_elem_id id; ++ unsigned int indirect; /* bit-field causes misalignment */ ++ union { ++ s32 integer[128]; ++ unsigned char data[512]; ++ s64 integer64[64]; ++ } value; ++ unsigned char reserved[128]; ++}; ++#endif /* CONFIG_X86_X32 */ + + /* get the value type and count of the control */ + static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, +@@ -219,9 +232,11 @@ static int get_elem_size(int type, int c + + static int copy_ctl_value_from_user(struct snd_card *card, + struct snd_ctl_elem_value *data, +- struct snd_ctl_elem_value32 __user *data32, ++ void __user *userdata, ++ void __user *valuep, + int *typep, int *countp) + { ++ struct snd_ctl_elem_value32 __user *data32 = userdata; + int i, type, size; + int uninitialized_var(count); + unsigned int indirect; +@@ -239,8 +254,9 @@ static int copy_ctl_value_from_user(stru + if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || + type == SNDRV_CTL_ELEM_TYPE_INTEGER) { + for (i = 0; i < count; i++) { ++ s32 __user *intp = valuep; + int val; +- if (get_user(val, &data32->value.integer[i])) ++ if (get_user(val, &intp[i])) + return -EFAULT; + data->value.integer.value[i] = val; + } +@@ -250,8 +266,7 @@ static int copy_ctl_value_from_user(stru + dev_err(card->dev, "snd_ioctl32_ctl_elem_value: unknown type %d\n", type); + return -EINVAL; + } +- if (copy_from_user(data->value.bytes.data, +- data32->value.data, size)) ++ if (copy_from_user(data->value.bytes.data, valuep, size)) + return -EFAULT; + } + +@@ -261,7 +276,8 @@ static int copy_ctl_value_from_user(stru + } + + /* restore the value to 32bit */ +-static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32, ++static int copy_ctl_value_to_user(void __user *userdata, ++ void __user *valuep, + struct snd_ctl_elem_value *data, + int type, int count) + { +@@ -270,22 +286,22 @@ static int copy_ctl_value_to_user(struct + if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || + type == SNDRV_CTL_ELEM_TYPE_INTEGER) { + for (i = 0; i < count; i++) { ++ s32 __user *intp = valuep; + int val; + val = data->value.integer.value[i]; +- if (put_user(val, &data32->value.integer[i])) ++ if (put_user(val, &intp[i])) + return -EFAULT; + } + } else { + size = get_elem_size(type, count); +- if (copy_to_user(data32->value.data, +- data->value.bytes.data, size)) ++ if (copy_to_user(valuep, data->value.bytes.data, size)) + return -EFAULT; + } + return 0; + } + +-static int snd_ctl_elem_read_user_compat(struct snd_card *card, +- struct snd_ctl_elem_value32 __user *data32) ++static int ctl_elem_read_user(struct snd_card *card, ++ void __user *userdata, void __user *valuep) + { + struct snd_ctl_elem_value *data; + int err, type, count; +@@ -294,7 +310,9 @@ static int snd_ctl_elem_read_user_compat + if (data == NULL) + return -ENOMEM; + +- if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0) ++ err = copy_ctl_value_from_user(card, data, userdata, valuep, ++ &type, &count); ++ if (err < 0) + goto error; + + snd_power_lock(card); +@@ -303,14 +321,15 @@ static int snd_ctl_elem_read_user_compat + err = snd_ctl_elem_read(card, data); + snd_power_unlock(card); + if (err >= 0) +- err = copy_ctl_value_to_user(data32, data, type, count); ++ err = copy_ctl_value_to_user(userdata, valuep, data, ++ type, count); + error: + kfree(data); + return err; + } + +-static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file, +- struct snd_ctl_elem_value32 __user *data32) ++static int ctl_elem_write_user(struct snd_ctl_file *file, ++ void __user *userdata, void __user *valuep) + { + struct snd_ctl_elem_value *data; + struct snd_card *card = file->card; +@@ -320,7 +339,9 @@ static int snd_ctl_elem_write_user_compa + if (data == NULL) + return -ENOMEM; + +- if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0) ++ err = copy_ctl_value_from_user(card, data, userdata, valuep, ++ &type, &count); ++ if (err < 0) + goto error; + + snd_power_lock(card); +@@ -329,12 +350,39 @@ static int snd_ctl_elem_write_user_compa + err = snd_ctl_elem_write(card, file, data); + snd_power_unlock(card); + if (err >= 0) +- err = copy_ctl_value_to_user(data32, data, type, count); ++ err = copy_ctl_value_to_user(userdata, valuep, data, ++ type, count); + error: + kfree(data); + return err; + } + ++static int snd_ctl_elem_read_user_compat(struct snd_card *card, ++ struct snd_ctl_elem_value32 __user *data32) ++{ ++ return ctl_elem_read_user(card, data32, &data32->value); ++} ++ ++static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file, ++ struct snd_ctl_elem_value32 __user *data32) ++{ ++ return ctl_elem_write_user(file, data32, &data32->value); ++} ++ ++#ifdef CONFIG_X86_X32 ++static int snd_ctl_elem_read_user_x32(struct snd_card *card, ++ struct snd_ctl_elem_value_x32 __user *data32) ++{ ++ return ctl_elem_read_user(card, data32, &data32->value); ++} ++ ++static int snd_ctl_elem_write_user_x32(struct snd_ctl_file *file, ++ struct snd_ctl_elem_value_x32 __user *data32) ++{ ++ return ctl_elem_write_user(file, data32, &data32->value); ++} ++#endif /* CONFIG_X86_X32 */ ++ + /* add or replace a user control */ + static int snd_ctl_elem_add_compat(struct snd_ctl_file *file, + struct snd_ctl_elem_info32 __user *data32, +@@ -393,6 +441,10 @@ enum { + SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32), + SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32), + SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32), ++#ifdef CONFIG_X86_X32 ++ SNDRV_CTL_IOCTL_ELEM_READ_X32 = _IOWR('U', 0x12, struct snd_ctl_elem_value_x32), ++ SNDRV_CTL_IOCTL_ELEM_WRITE_X32 = _IOWR('U', 0x13, struct snd_ctl_elem_value_x32), ++#endif /* CONFIG_X86_X32 */ + }; + + static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) +@@ -431,6 +483,12 @@ static inline long snd_ctl_ioctl_compat( + return snd_ctl_elem_add_compat(ctl, argp, 0); + case SNDRV_CTL_IOCTL_ELEM_REPLACE32: + return snd_ctl_elem_add_compat(ctl, argp, 1); ++#ifdef CONFIG_X86_X32 ++ case SNDRV_CTL_IOCTL_ELEM_READ_X32: ++ return snd_ctl_elem_read_user_x32(ctl->card, argp); ++ case SNDRV_CTL_IOCTL_ELEM_WRITE_X32: ++ return snd_ctl_elem_write_user_x32(ctl, argp); ++#endif /* CONFIG_X86_X32 */ + } + + down_read(&snd_ioctl_rwsem); diff --git a/queue-4.4/alsa-hda-fix-mic-issues-on-acer-aspire-e1-472.patch b/queue-4.4/alsa-hda-fix-mic-issues-on-acer-aspire-e1-472.patch new file mode 100644 index 00000000000..759a6acbc57 --- /dev/null +++ b/queue-4.4/alsa-hda-fix-mic-issues-on-acer-aspire-e1-472.patch @@ -0,0 +1,34 @@ +From 02322ac9dee9aff8d8862e8d6660ebe102f492ea Mon Sep 17 00:00:00 2001 +From: Simon South +Date: Wed, 2 Mar 2016 23:10:44 -0500 +Subject: ALSA: hda - Fix mic issues on Acer Aspire E1-472 + +From: Simon South + +commit 02322ac9dee9aff8d8862e8d6660ebe102f492ea upstream. + +This patch applies the microphone-related fix created for the Acer +Aspire E1-572 to the E1-472 as well, as it uses the same Realtek ALC282 +CODEC and demonstrates the same issues. + +This patch allows an external, headset microphone to be used and limits +the gain on the (quite noisy) internal microphone. + +Signed-off-by: Simon South +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5386,6 +5386,7 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), + SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), ++ SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), + SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), + SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), + SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK), diff --git a/queue-4.4/alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch b/queue-4.4/alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch new file mode 100644 index 00000000000..940c31e1585 --- /dev/null +++ b/queue-4.4/alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch @@ -0,0 +1,39 @@ +From eab3c4db193f5fcccf70e884de9a922ca2c63d80 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 29 Feb 2016 14:26:43 +0100 +Subject: ALSA: hdsp: Fix wrong boolean ctl value accesses + +From: Takashi Iwai + +commit eab3c4db193f5fcccf70e884de9a922ca2c63d80 upstream. + +snd-hdsp driver accesses enum item values (int) instead of boolean +values (long) wrongly for some ctl elements. This patch fixes them. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/rme9652/hdsp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/sound/pci/rme9652/hdsp.c ++++ b/sound/pci/rme9652/hdsp.c +@@ -2879,7 +2879,7 @@ static int snd_hdsp_get_dds_offset(struc + { + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + +- ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp); ++ ucontrol->value.integer.value[0] = hdsp_dds_offset(hdsp); + return 0; + } + +@@ -2891,7 +2891,7 @@ static int snd_hdsp_put_dds_offset(struc + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; +- val = ucontrol->value.enumerated.item[0]; ++ val = ucontrol->value.integer.value[0]; + spin_lock_irq(&hdsp->lock); + if (val != hdsp_dds_offset(hdsp)) + change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0; diff --git a/queue-4.4/alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch b/queue-4.4/alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch new file mode 100644 index 00000000000..9b545ab92d9 --- /dev/null +++ b/queue-4.4/alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch @@ -0,0 +1,50 @@ +From 537e48136295c5860a92138c5ea3959b9542868b Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 29 Feb 2016 14:25:16 +0100 +Subject: ALSA: hdspm: Fix wrong boolean ctl value accesses + +From: Takashi Iwai + +commit 537e48136295c5860a92138c5ea3959b9542868b upstream. + +snd-hdspm driver accesses enum item values (int) instead of boolean +values (long) wrongly for some ctl elements. This patch fixes them. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/rme9652/hdspm.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/sound/pci/rme9652/hdspm.c ++++ b/sound/pci/rme9652/hdspm.c +@@ -2261,7 +2261,7 @@ static int snd_hdspm_put_system_sample_r + { + struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); + +- hdspm_set_dds_value(hdspm, ucontrol->value.enumerated.item[0]); ++ hdspm_set_dds_value(hdspm, ucontrol->value.integer.value[0]); + return 0; + } + +@@ -4449,7 +4449,7 @@ static int snd_hdspm_get_tco_word_term(s + { + struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); + +- ucontrol->value.enumerated.item[0] = hdspm->tco->term; ++ ucontrol->value.integer.value[0] = hdspm->tco->term; + + return 0; + } +@@ -4460,8 +4460,8 @@ static int snd_hdspm_put_tco_word_term(s + { + struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); + +- if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) { +- hdspm->tco->term = ucontrol->value.enumerated.item[0]; ++ if (hdspm->tco->term != ucontrol->value.integer.value[0]) { ++ hdspm->tco->term = ucontrol->value.integer.value[0]; + + hdspm_tco_write(hdspm); + diff --git a/queue-4.4/alsa-hdspm-fix-zero-division.patch b/queue-4.4/alsa-hdspm-fix-zero-division.patch new file mode 100644 index 00000000000..e82ccc8bdfc --- /dev/null +++ b/queue-4.4/alsa-hdspm-fix-zero-division.patch @@ -0,0 +1,53 @@ +From c1099c3294c2344110085a38c50e478a5992b368 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 29 Feb 2016 14:32:42 +0100 +Subject: ALSA: hdspm: Fix zero-division + +From: Takashi Iwai + +commit c1099c3294c2344110085a38c50e478a5992b368 upstream. + +HDSPM driver contains a code issuing zero-division potentially in +system sample rate ctl code. This patch fixes it by not processing +a zero or invalid rate value as a divisor, as well as excluding the +invalid value to be passed via the given ctl element. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/rme9652/hdspm.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/sound/pci/rme9652/hdspm.c ++++ b/sound/pci/rme9652/hdspm.c +@@ -1601,6 +1601,9 @@ static void hdspm_set_dds_value(struct h + { + u64 n; + ++ if (snd_BUG_ON(rate <= 0)) ++ return; ++ + if (rate >= 112000) + rate /= 4; + else if (rate >= 56000) +@@ -2215,6 +2218,8 @@ static int hdspm_get_system_sample_rate( + } else { + /* slave mode, return external sample rate */ + rate = hdspm_external_sample_rate(hdspm); ++ if (!rate) ++ rate = hdspm->system_sample_rate; + } + } + +@@ -2260,7 +2265,10 @@ static int snd_hdspm_put_system_sample_r + ucontrol) + { + struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); ++ int rate = ucontrol->value.integer.value[0]; + ++ if (rate < 27000 || rate > 207000) ++ return -EINVAL; + hdspm_set_dds_value(hdspm, ucontrol->value.integer.value[0]); + return 0; + } diff --git a/queue-4.4/alsa-pcm-fix-ioctls-for-x32-abi.patch b/queue-4.4/alsa-pcm-fix-ioctls-for-x32-abi.patch new file mode 100644 index 00000000000..778054a8d3a --- /dev/null +++ b/queue-4.4/alsa-pcm-fix-ioctls-for-x32-abi.patch @@ -0,0 +1,237 @@ +From 513ace79b657e2022a592e77f24074e088681ecc Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sun, 28 Feb 2016 11:23:09 +0100 +Subject: ALSA: pcm: Fix ioctls for X32 ABI + +From: Takashi Iwai + +commit 513ace79b657e2022a592e77f24074e088681ecc upstream. + +X32 ABI uses the 64bit timespec in addition to 64bit alignment of +64bit values. This leads to incompatibilities in some PCM ioctls +involved with snd_pcm_channel_info, snd_pcm_status and +snd_pcm_sync_ptr structs. Fix the PCM compat ABI for these ioctls +like the previous commit for ctl API. + +Reported-by: Steven Newbury +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/pcm_compat.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 176 insertions(+), 1 deletion(-) + +--- a/sound/core/pcm_compat.c ++++ b/sound/core/pcm_compat.c +@@ -183,6 +183,14 @@ static int snd_pcm_ioctl_channel_info_co + return err; + } + ++#ifdef CONFIG_X86_X32 ++/* X32 ABI has the same struct as x86-64 for snd_pcm_channel_info */ ++static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream, ++ struct snd_pcm_channel_info __user *src); ++#define snd_pcm_ioctl_channel_info_x32(s, p) \ ++ snd_pcm_channel_info_user(s, p) ++#endif /* CONFIG_X86_X32 */ ++ + struct snd_pcm_status32 { + s32 state; + struct compat_timespec trigger_tstamp; +@@ -243,6 +251,71 @@ static int snd_pcm_status_user_compat(st + return err; + } + ++#ifdef CONFIG_X86_X32 ++/* X32 ABI has 64bit timespec and 64bit alignment */ ++struct snd_pcm_status_x32 { ++ s32 state; ++ u32 rsvd; /* alignment */ ++ struct timespec trigger_tstamp; ++ struct timespec tstamp; ++ u32 appl_ptr; ++ u32 hw_ptr; ++ s32 delay; ++ u32 avail; ++ u32 avail_max; ++ u32 overrange; ++ s32 suspended_state; ++ u32 audio_tstamp_data; ++ struct timespec audio_tstamp; ++ struct timespec driver_tstamp; ++ u32 audio_tstamp_accuracy; ++ unsigned char reserved[52-2*sizeof(struct timespec)]; ++} __packed; ++ ++#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst)) ++ ++static int snd_pcm_status_user_x32(struct snd_pcm_substream *substream, ++ struct snd_pcm_status_x32 __user *src, ++ bool ext) ++{ ++ struct snd_pcm_status status; ++ int err; ++ ++ memset(&status, 0, sizeof(status)); ++ /* ++ * with extension, parameters are read/write, ++ * get audio_tstamp_data from user, ++ * ignore rest of status structure ++ */ ++ if (ext && get_user(status.audio_tstamp_data, ++ (u32 __user *)(&src->audio_tstamp_data))) ++ return -EFAULT; ++ err = snd_pcm_status(substream, &status); ++ if (err < 0) ++ return err; ++ ++ if (clear_user(src, sizeof(*src))) ++ return -EFAULT; ++ if (put_user(status.state, &src->state) || ++ put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) || ++ put_timespec(&status.tstamp, &src->tstamp) || ++ put_user(status.appl_ptr, &src->appl_ptr) || ++ put_user(status.hw_ptr, &src->hw_ptr) || ++ put_user(status.delay, &src->delay) || ++ put_user(status.avail, &src->avail) || ++ put_user(status.avail_max, &src->avail_max) || ++ put_user(status.overrange, &src->overrange) || ++ put_user(status.suspended_state, &src->suspended_state) || ++ put_user(status.audio_tstamp_data, &src->audio_tstamp_data) || ++ put_timespec(&status.audio_tstamp, &src->audio_tstamp) || ++ put_timespec(&status.driver_tstamp, &src->driver_tstamp) || ++ put_user(status.audio_tstamp_accuracy, &src->audio_tstamp_accuracy)) ++ return -EFAULT; ++ ++ return err; ++} ++#endif /* CONFIG_X86_X32 */ ++ + /* both for HW_PARAMS and HW_REFINE */ + static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream, + int refine, +@@ -469,6 +542,93 @@ static int snd_pcm_ioctl_sync_ptr_compat + return 0; + } + ++#ifdef CONFIG_X86_X32 ++/* X32 ABI has 64bit timespec and 64bit alignment */ ++struct snd_pcm_mmap_status_x32 { ++ s32 state; ++ s32 pad1; ++ u32 hw_ptr; ++ u32 pad2; /* alignment */ ++ struct timespec tstamp; ++ s32 suspended_state; ++ struct timespec audio_tstamp; ++} __packed; ++ ++struct snd_pcm_mmap_control_x32 { ++ u32 appl_ptr; ++ u32 avail_min; ++}; ++ ++struct snd_pcm_sync_ptr_x32 { ++ u32 flags; ++ u32 rsvd; /* alignment */ ++ union { ++ struct snd_pcm_mmap_status_x32 status; ++ unsigned char reserved[64]; ++ } s; ++ union { ++ struct snd_pcm_mmap_control_x32 control; ++ unsigned char reserved[64]; ++ } c; ++} __packed; ++ ++static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream, ++ struct snd_pcm_sync_ptr_x32 __user *src) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ volatile struct snd_pcm_mmap_status *status; ++ volatile struct snd_pcm_mmap_control *control; ++ u32 sflags; ++ struct snd_pcm_mmap_control scontrol; ++ struct snd_pcm_mmap_status sstatus; ++ snd_pcm_uframes_t boundary; ++ int err; ++ ++ if (snd_BUG_ON(!runtime)) ++ return -EINVAL; ++ ++ if (get_user(sflags, &src->flags) || ++ get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) || ++ get_user(scontrol.avail_min, &src->c.control.avail_min)) ++ return -EFAULT; ++ if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) { ++ err = snd_pcm_hwsync(substream); ++ if (err < 0) ++ return err; ++ } ++ status = runtime->status; ++ control = runtime->control; ++ boundary = recalculate_boundary(runtime); ++ if (!boundary) ++ boundary = 0x7fffffff; ++ snd_pcm_stream_lock_irq(substream); ++ /* FIXME: we should consider the boundary for the sync from app */ ++ if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL)) ++ control->appl_ptr = scontrol.appl_ptr; ++ else ++ scontrol.appl_ptr = control->appl_ptr % boundary; ++ if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN)) ++ control->avail_min = scontrol.avail_min; ++ else ++ scontrol.avail_min = control->avail_min; ++ sstatus.state = status->state; ++ sstatus.hw_ptr = status->hw_ptr % boundary; ++ sstatus.tstamp = status->tstamp; ++ sstatus.suspended_state = status->suspended_state; ++ sstatus.audio_tstamp = status->audio_tstamp; ++ snd_pcm_stream_unlock_irq(substream); ++ if (put_user(sstatus.state, &src->s.status.state) || ++ put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) || ++ put_timespec(&sstatus.tstamp, &src->s.status.tstamp) || ++ put_user(sstatus.suspended_state, &src->s.status.suspended_state) || ++ put_timespec(&sstatus.audio_tstamp, &src->s.status.audio_tstamp) || ++ put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) || ++ put_user(scontrol.avail_min, &src->c.control.avail_min)) ++ return -EFAULT; ++ ++ return 0; ++} ++#endif /* CONFIG_X86_X32 */ + + /* + */ +@@ -487,7 +647,12 @@ enum { + SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct snd_xfern32), + SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32), + SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr32), +- ++#ifdef CONFIG_X86_X32 ++ SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 = _IOR('A', 0x32, struct snd_pcm_channel_info), ++ SNDRV_PCM_IOCTL_STATUS_X32 = _IOR('A', 0x20, struct snd_pcm_status_x32), ++ SNDRV_PCM_IOCTL_STATUS_EXT_X32 = _IOWR('A', 0x24, struct snd_pcm_status_x32), ++ SNDRV_PCM_IOCTL_SYNC_PTR_X32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr_x32), ++#endif /* CONFIG_X86_X32 */ + }; + + static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) +@@ -559,6 +724,16 @@ static long snd_pcm_ioctl_compat(struct + return snd_pcm_ioctl_rewind_compat(substream, argp); + case SNDRV_PCM_IOCTL_FORWARD32: + return snd_pcm_ioctl_forward_compat(substream, argp); ++#ifdef CONFIG_X86_X32 ++ case SNDRV_PCM_IOCTL_STATUS_X32: ++ return snd_pcm_status_user_x32(substream, argp, false); ++ case SNDRV_PCM_IOCTL_STATUS_EXT_X32: ++ return snd_pcm_status_user_x32(substream, argp, true); ++ case SNDRV_PCM_IOCTL_SYNC_PTR_X32: ++ return snd_pcm_ioctl_sync_ptr_x32(substream, argp); ++ case SNDRV_PCM_IOCTL_CHANNEL_INFO_X32: ++ return snd_pcm_ioctl_channel_info_x32(substream, argp); ++#endif /* CONFIG_X86_X32 */ + } + + return -ENOIOCTLCMD; diff --git a/queue-4.4/alsa-rawmidi-fix-ioctls-x32-abi.patch b/queue-4.4/alsa-rawmidi-fix-ioctls-x32-abi.patch new file mode 100644 index 00000000000..8434236c9c0 --- /dev/null +++ b/queue-4.4/alsa-rawmidi-fix-ioctls-x32-abi.patch @@ -0,0 +1,95 @@ +From 2251fbbc1539f05b0b206b37a602d5776be37252 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sun, 28 Feb 2016 11:28:08 +0100 +Subject: ALSA: rawmidi: Fix ioctls X32 ABI + +From: Takashi Iwai + +commit 2251fbbc1539f05b0b206b37a602d5776be37252 upstream. + +Like the previous fixes for ctl and PCM, we need a fix for +incompatible X32 ABI regarding the rawmidi: namely, struct +snd_rawmidi_status has the timespec, and the size and the alignment on +X32 differ from IA32. + +This patch fixes the incompatible ioctl for X32. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/rawmidi_compat.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 53 insertions(+) + +--- a/sound/core/rawmidi_compat.c ++++ b/sound/core/rawmidi_compat.c +@@ -94,9 +94,58 @@ static int snd_rawmidi_ioctl_status_comp + return 0; + } + ++#ifdef CONFIG_X86_X32 ++/* X32 ABI has 64bit timespec and 64bit alignment */ ++struct snd_rawmidi_status_x32 { ++ s32 stream; ++ u32 rsvd; /* alignment */ ++ struct timespec tstamp; ++ u32 avail; ++ u32 xruns; ++ unsigned char reserved[16]; ++} __attribute__((packed)); ++ ++#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst)) ++ ++static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile, ++ struct snd_rawmidi_status_x32 __user *src) ++{ ++ int err; ++ struct snd_rawmidi_status status; ++ ++ if (rfile->output == NULL) ++ return -EINVAL; ++ if (get_user(status.stream, &src->stream)) ++ return -EFAULT; ++ ++ switch (status.stream) { ++ case SNDRV_RAWMIDI_STREAM_OUTPUT: ++ err = snd_rawmidi_output_status(rfile->output, &status); ++ break; ++ case SNDRV_RAWMIDI_STREAM_INPUT: ++ err = snd_rawmidi_input_status(rfile->input, &status); ++ break; ++ default: ++ return -EINVAL; ++ } ++ if (err < 0) ++ return err; ++ ++ if (put_timespec(&status.tstamp, &src->tstamp) || ++ put_user(status.avail, &src->avail) || ++ put_user(status.xruns, &src->xruns)) ++ return -EFAULT; ++ ++ return 0; ++} ++#endif /* CONFIG_X86_X32 */ ++ + enum { + SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32), + SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct snd_rawmidi_status32), ++#ifdef CONFIG_X86_X32 ++ SNDRV_RAWMIDI_IOCTL_STATUS_X32 = _IOWR('W', 0x20, struct snd_rawmidi_status_x32), ++#endif /* CONFIG_X86_X32 */ + }; + + static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) +@@ -115,6 +164,10 @@ static long snd_rawmidi_ioctl_compat(str + return snd_rawmidi_ioctl_params_compat(rfile, argp); + case SNDRV_RAWMIDI_IOCTL_STATUS32: + return snd_rawmidi_ioctl_status_compat(rfile, argp); ++#ifdef CONFIG_X86_X32 ++ case SNDRV_RAWMIDI_IOCTL_STATUS_X32: ++ return snd_rawmidi_ioctl_status_x32(rfile, argp); ++#endif /* CONFIG_X86_X32 */ + } + return -ENOIOCTLCMD; + } diff --git a/queue-4.4/alsa-seq-oss-don-t-drain-at-closing-a-client.patch b/queue-4.4/alsa-seq-oss-don-t-drain-at-closing-a-client.patch new file mode 100644 index 00000000000..62a52c0e196 --- /dev/null +++ b/queue-4.4/alsa-seq-oss-don-t-drain-at-closing-a-client.patch @@ -0,0 +1,81 @@ +From 197b958c1e76a575d77038cc98b4bebc2134279f Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 1 Mar 2016 18:30:18 +0100 +Subject: ALSA: seq: oss: Don't drain at closing a client + +From: Takashi Iwai + +commit 197b958c1e76a575d77038cc98b4bebc2134279f upstream. + +The OSS sequencer client tries to drain the pending events at +releasing. Unfortunately, as spotted by syzkaller fuzzer, this may +lead to an unkillable process state when the event has been queued at +the far future. Since the process being released can't be signaled +any longer, it remains and waits for the echo-back event in that far +future. + +Back to history, the draining feature was implemented at the time we +misinterpreted POSIX definition for blocking file operation. +Actually, such a behavior is superfluous at release, and we should +just release the device as is instead of keeping it up forever. + +This patch just removes the draining call that may block the release +for too long time unexpectedly. + +BugLink: http://lkml.kernel.org/r/CACT4Y+Y4kD-aBGj37rf-xBw9bH3GMU6P+MYg4W1e-s-paVD2pg@mail.gmail.com +Reported-by: Dmitry Vyukov +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/seq/oss/seq_oss.c | 2 -- + sound/core/seq/oss/seq_oss_device.h | 1 - + sound/core/seq/oss/seq_oss_init.c | 16 ---------------- + 3 files changed, 19 deletions(-) + +--- a/sound/core/seq/oss/seq_oss.c ++++ b/sound/core/seq/oss/seq_oss.c +@@ -148,8 +148,6 @@ odev_release(struct inode *inode, struct + if ((dp = file->private_data) == NULL) + return 0; + +- snd_seq_oss_drain_write(dp); +- + mutex_lock(®ister_mutex); + snd_seq_oss_release(dp); + mutex_unlock(®ister_mutex); +--- a/sound/core/seq/oss/seq_oss_device.h ++++ b/sound/core/seq/oss/seq_oss_device.h +@@ -127,7 +127,6 @@ int snd_seq_oss_write(struct seq_oss_dev + unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait); + + void snd_seq_oss_reset(struct seq_oss_devinfo *dp); +-void snd_seq_oss_drain_write(struct seq_oss_devinfo *dp); + + /* */ + void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time); +--- a/sound/core/seq/oss/seq_oss_init.c ++++ b/sound/core/seq/oss/seq_oss_init.c +@@ -436,22 +436,6 @@ snd_seq_oss_release(struct seq_oss_devin + + + /* +- * Wait until the queue is empty (if we don't have nonblock) +- */ +-void +-snd_seq_oss_drain_write(struct seq_oss_devinfo *dp) +-{ +- if (! dp->timer->running) +- return; +- if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) && +- dp->writeq) { +- while (snd_seq_oss_writeq_sync(dp->writeq)) +- ; +- } +-} +- +- +-/* + * reset sequencer devices + */ + void diff --git a/queue-4.4/alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch b/queue-4.4/alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch new file mode 100644 index 00000000000..8605177d5b5 --- /dev/null +++ b/queue-4.4/alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch @@ -0,0 +1,39 @@ +From 3a72494ac2a3bd229db941d51e7efe2f6ccd947b Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sun, 28 Feb 2016 11:36:14 +0100 +Subject: ALSA: timer: Fix broken compat timer user status ioctl + +From: Takashi Iwai + +commit 3a72494ac2a3bd229db941d51e7efe2f6ccd947b upstream. + +The timer user status compat ioctl returned the bogus struct used for +64bit architectures instead of the 32bit one. This patch addresses +it to return the proper struct. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/timer_compat.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/sound/core/timer_compat.c ++++ b/sound/core/timer_compat.c +@@ -70,13 +70,14 @@ static int snd_timer_user_status_compat( + struct snd_timer_status32 __user *_status) + { + struct snd_timer_user *tu; +- struct snd_timer_status status; ++ struct snd_timer_status32 status; + + tu = file->private_data; + if (snd_BUG_ON(!tu->timeri)) + return -ENXIO; + memset(&status, 0, sizeof(status)); +- status.tstamp = tu->tstamp; ++ status.tstamp.tv_sec = tu->tstamp.tv_sec; ++ status.tstamp.tv_nsec = tu->tstamp.tv_nsec; + status.resolution = snd_timer_resolution(tu->timeri); + status.lost = tu->timeri->lost; + status.overrun = tu->overrun; diff --git a/queue-4.4/alsa-timer-fix-ioctls-for-x32-abi.patch b/queue-4.4/alsa-timer-fix-ioctls-for-x32-abi.patch new file mode 100644 index 00000000000..ea1243f81fd --- /dev/null +++ b/queue-4.4/alsa-timer-fix-ioctls-for-x32-abi.patch @@ -0,0 +1,59 @@ +From b24e7ad1fdc22177eb3e51584e1cfcb45d818488 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sun, 28 Feb 2016 11:41:47 +0100 +Subject: ALSA: timer: Fix ioctls for X32 ABI + +From: Takashi Iwai + +commit b24e7ad1fdc22177eb3e51584e1cfcb45d818488 upstream. + +X32 ABI takes the 64bit timespec, thus the timer user status ioctl becomes +incompatible with IA32. This results in NOTTY error when the ioctl is +issued. + +Meanwhile, this struct in X32 is essentially identical with the one in +X86-64, so we can just bypassing to the existing code for this +specific compat ioctl. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/timer_compat.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/sound/core/timer_compat.c ++++ b/sound/core/timer_compat.c +@@ -88,12 +88,21 @@ static int snd_timer_user_status_compat( + return 0; + } + ++#ifdef CONFIG_X86_X32 ++/* X32 ABI has the same struct as x86-64 */ ++#define snd_timer_user_status_x32(file, s) \ ++ snd_timer_user_status(file, s) ++#endif /* CONFIG_X86_X32 */ ++ + /* + */ + + enum { + SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32), + SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32), ++#ifdef CONFIG_X86_X32 ++ SNDRV_TIMER_IOCTL_STATUS_X32 = _IOW('T', 0x14, struct snd_timer_status), ++#endif /* CONFIG_X86_X32 */ + }; + + static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) +@@ -122,6 +131,10 @@ static long snd_timer_user_ioctl_compat( + return snd_timer_user_info_compat(file, argp); + case SNDRV_TIMER_IOCTL_STATUS32: + return snd_timer_user_status_compat(file, argp); ++#ifdef CONFIG_X86_X32 ++ case SNDRV_TIMER_IOCTL_STATUS_X32: ++ return snd_timer_user_status_x32(file, argp); ++#endif /* CONFIG_X86_X32 */ + } + return -ENOIOCTLCMD; + } diff --git a/queue-4.4/alsa-usb-audio-add-a-quirk-for-plantronics-da45.patch b/queue-4.4/alsa-usb-audio-add-a-quirk-for-plantronics-da45.patch new file mode 100644 index 00000000000..51cec883534 --- /dev/null +++ b/queue-4.4/alsa-usb-audio-add-a-quirk-for-plantronics-da45.patch @@ -0,0 +1,32 @@ +From 17e2df4613be57d0fab68df749f6b8114e453152 Mon Sep 17 00:00:00 2001 +From: Dennis Kadioglu +Date: Tue, 1 Mar 2016 14:23:29 +0100 +Subject: ALSA: usb-audio: Add a quirk for Plantronics DA45 + +From: Dennis Kadioglu + +commit 17e2df4613be57d0fab68df749f6b8114e453152 upstream. + +Plantronics DA45 does not support reading the sample rate which leads +to many lines of "cannot get freq at ep 0x4" and "cannot get freq at +ep 0x84". This patch adds the USB ID of the DA45 to quirks.c and +avoids those error messages. + +Signed-off-by: Dennis Kadioglu +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/quirks.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1124,6 +1124,7 @@ bool snd_usb_get_sample_rate_quirk(struc + case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */ + case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */ + case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */ ++ case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */ + case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ + case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ + case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */ diff --git a/queue-4.4/dmaengine-pxa_dma-fix-cyclic-transfers.patch b/queue-4.4/dmaengine-pxa_dma-fix-cyclic-transfers.patch new file mode 100644 index 00000000000..de140e03c47 --- /dev/null +++ b/queue-4.4/dmaengine-pxa_dma-fix-cyclic-transfers.patch @@ -0,0 +1,61 @@ +From f16921275cc3c2442d0b95225785a601603b990f Mon Sep 17 00:00:00 2001 +From: Robert Jarzmik +Date: Tue, 16 Feb 2016 22:54:02 +0100 +Subject: dmaengine: pxa_dma: fix cyclic transfers + +From: Robert Jarzmik + +commit f16921275cc3c2442d0b95225785a601603b990f upstream. + +While testing audio with pxa2xx-ac97, underrun were happening while the +user application was correctly feeding the music. Debug proved that the +cyclic transfer is not cyclic, ie. the last descriptor did not loop on +the first. + +Another issue is that the descriptor length was always set to 8192, +because of an trivial operator issue. + +This was tested on a pxa27x platform. + +Fixes: a57e16cf0333 ("dmaengine: pxa: add pxa dmaengine driver") +Reported-by: Vasily Khoruzhick +Tested-by: Vasily Khoruzhick +Signed-off-by: Robert Jarzmik +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/pxa_dma.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/dma/pxa_dma.c ++++ b/drivers/dma/pxa_dma.c +@@ -583,6 +583,8 @@ static void set_updater_desc(struct pxad + (PXA_DCMD_LENGTH & sizeof(u32)); + if (flags & DMA_PREP_INTERRUPT) + updater->dcmd |= PXA_DCMD_ENDIRQEN; ++ if (sw_desc->cyclic) ++ sw_desc->hw_desc[sw_desc->nb_desc - 2]->ddadr = sw_desc->first; + } + + static bool is_desc_completed(struct virt_dma_desc *vd) +@@ -673,6 +675,10 @@ static irqreturn_t pxad_chan_handler(int + dev_dbg(&chan->vc.chan.dev->device, + "%s(): checking txd %p[%x]: completed=%d\n", + __func__, vd, vd->tx.cookie, is_desc_completed(vd)); ++ if (to_pxad_sw_desc(vd)->cyclic) { ++ vchan_cyclic_callback(vd); ++ break; ++ } + if (is_desc_completed(vd)) { + list_del(&vd->node); + vchan_cookie_complete(vd); +@@ -1080,7 +1086,7 @@ pxad_prep_dma_cyclic(struct dma_chan *dc + return NULL; + + pxad_get_config(chan, dir, &dcmd, &dsadr, &dtadr); +- dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH | period_len); ++ dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH & period_len); + dev_dbg(&chan->vc.chan.dev->device, + "%s(): buf_addr=0x%lx len=%zu period=%zu dir=%d flags=%lx\n", + __func__, (unsigned long)buf_addr, len, period_len, dir, flags); diff --git a/queue-4.4/series b/queue-4.4/series index 894b79ccd80..1187548fa0d 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -40,3 +40,16 @@ btrfs-fix-loading-of-orphan-roots-leading-to-bug_on.patch revert-jffs2-fix-lock-acquisition-order-bug-in-jffs2_write_begin.patch jffs2-fix-page-lock-f-sem-deadlock.patch fix-directory-hardlinks-from-deleted-directories.patch +dmaengine-pxa_dma-fix-cyclic-transfers.patch +adv7604-fix-tx-5v-detect-regression.patch +alsa-usb-audio-add-a-quirk-for-plantronics-da45.patch +alsa-ctl-fix-ioctls-for-x32-abi.patch +alsa-hda-fix-mic-issues-on-acer-aspire-e1-472.patch +alsa-rawmidi-fix-ioctls-x32-abi.patch +alsa-timer-fix-ioctls-for-x32-abi.patch +alsa-pcm-fix-ioctls-for-x32-abi.patch +alsa-seq-oss-don-t-drain-at-closing-a-client.patch +alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch +alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch +alsa-hdspm-fix-zero-division.patch +alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch