From: Greg Kroah-Hartman Date: Wed, 24 Nov 2021 08:31:16 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v5.15.5~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=19ebddc1686d206799ba62d2f7352222ae8e2cfa;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: asoc-dapm-cover-regression-by-kctl-change-notification-fix.patch usb-max-3421-use-driver-data-instead-of-maintaining-a-list-of-bound-devices.patch --- diff --git a/queue-4.9/asoc-dapm-cover-regression-by-kctl-change-notification-fix.patch b/queue-4.9/asoc-dapm-cover-regression-by-kctl-change-notification-fix.patch new file mode 100644 index 00000000000..188da714ece --- /dev/null +++ b/queue-4.9/asoc-dapm-cover-regression-by-kctl-change-notification-fix.patch @@ -0,0 +1,82 @@ +From 827b0913a9d9d07a0c3e559dbb20ca4d6d285a54 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 5 Nov 2021 10:09:25 +0100 +Subject: ASoC: DAPM: Cover regression by kctl change notification fix + +From: Takashi Iwai + +commit 827b0913a9d9d07a0c3e559dbb20ca4d6d285a54 upstream. + +The recent fix for DAPM to correct the kctl change notification by the +commit 5af82c81b2c4 ("ASoC: DAPM: Fix missing kctl change +notifications") caused other regressions since it changed the behavior +of snd_soc_dapm_set_pin() that is called from several API functions. +Formerly it returned always 0 for success, but now it returns 0 or 1. + +This patch addresses it, restoring the old behavior of +snd_soc_dapm_set_pin() while keeping the fix in +snd_soc_dapm_put_pin_switch(). + +Fixes: 5af82c81b2c4 ("ASoC: DAPM: Fix missing kctl change notifications") +Reported-by: Yu-Hsuan Hsu +Cc: +Signed-off-by: Takashi Iwai +Link: https://lore.kernel.org/r/20211105090925.20575-1-tiwai@suse.de +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/soc-dapm.c | 29 +++++++++++++++++++++++------ + 1 file changed, 23 insertions(+), 6 deletions(-) + +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -2406,8 +2406,13 @@ static struct snd_soc_dapm_widget *dapm_ + return NULL; + } + +-static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, +- const char *pin, int status) ++/* ++ * set the DAPM pin status: ++ * returns 1 when the value has been updated, 0 when unchanged, or a negative ++ * error code; called from kcontrol put callback ++ */ ++static int __snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, ++ const char *pin, int status) + { + struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); + int ret = 0; +@@ -2433,6 +2438,18 @@ static int snd_soc_dapm_set_pin(struct s + return ret; + } + ++/* ++ * similar as __snd_soc_dapm_set_pin(), but returns 0 when successful; ++ * called from several API functions below ++ */ ++static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, ++ const char *pin, int status) ++{ ++ int ret = __snd_soc_dapm_set_pin(dapm, pin, status); ++ ++ return ret < 0 ? ret : 0; ++} ++ + /** + * snd_soc_dapm_sync_unlocked - scan and power dapm paths + * @dapm: DAPM context +@@ -3327,10 +3344,10 @@ int snd_soc_dapm_put_pin_switch(struct s + const char *pin = (const char *)kcontrol->private_value; + int ret; + +- if (ucontrol->value.integer.value[0]) +- ret = snd_soc_dapm_enable_pin(&card->dapm, pin); +- else +- ret = snd_soc_dapm_disable_pin(&card->dapm, pin); ++ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); ++ ret = __snd_soc_dapm_set_pin(&card->dapm, pin, ++ !!ucontrol->value.integer.value[0]); ++ mutex_unlock(&card->dapm_mutex); + + snd_soc_dapm_sync(&card->dapm); + return ret; diff --git a/queue-4.9/series b/queue-4.9/series index 297fa07475a..0904a21f5bb 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -202,3 +202,5 @@ batman-adv-mcast-fix-duplicate-mcast-packets-from-bla-backbone-to-mesh.patch batman-adv-consider-fragmentation-for-needed_headroom.patch batman-adv-reserve-needed_-room-for-fragments.patch batman-adv-don-t-always-reallocate-the-fragmentation-skb-head.patch +asoc-dapm-cover-regression-by-kctl-change-notification-fix.patch +usb-max-3421-use-driver-data-instead-of-maintaining-a-list-of-bound-devices.patch diff --git a/queue-4.9/usb-max-3421-use-driver-data-instead-of-maintaining-a-list-of-bound-devices.patch b/queue-4.9/usb-max-3421-use-driver-data-instead-of-maintaining-a-list-of-bound-devices.patch new file mode 100644 index 00000000000..82e5536ed86 --- /dev/null +++ b/queue-4.9/usb-max-3421-use-driver-data-instead-of-maintaining-a-list-of-bound-devices.patch @@ -0,0 +1,98 @@ +From fc153aba3ef371d0d76eb88230ed4e0dee5b38f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Mon, 18 Oct 2021 22:40:28 +0200 +Subject: usb: max-3421: Use driver data instead of maintaining a list of bound devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +commit fc153aba3ef371d0d76eb88230ed4e0dee5b38f2 upstream. + +Instead of maintaining a single-linked list of devices that must be +searched linearly in .remove() just use spi_set_drvdata() to remember the +link between the spi device and the driver struct. Then the global list +and the next member can be dropped. + +This simplifies the driver, reduces the memory footprint and the time to +search the list. Also it makes obvious that there is always a corresponding +driver struct for a given device in .remove(), so the error path for +!max3421_hcd can be dropped, too. + +As a side effect this fixes a data inconsistency when .probe() races with +itself for a second max3421 device in manipulating max3421_hcd_list. A +similar race is fixed in .remove(), too. + +Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.") +Signed-off-by: Uwe Kleine-König +Link: https://lore.kernel.org/r/20211018204028.2914597-1-u.kleine-koenig@pengutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/max3421-hcd.c | 25 +++++-------------------- + 1 file changed, 5 insertions(+), 20 deletions(-) + +--- a/drivers/usb/host/max3421-hcd.c ++++ b/drivers/usb/host/max3421-hcd.c +@@ -121,8 +121,6 @@ struct max3421_hcd { + + struct task_struct *spi_thread; + +- struct max3421_hcd *next; +- + enum max3421_rh_state rh_state; + /* lower 16 bits contain port status, upper 16 bits the change mask: */ + u32 port_status; +@@ -170,8 +168,6 @@ struct max3421_ep { + u8 retransmit; /* packet needs retransmission */ + }; + +-static struct max3421_hcd *max3421_hcd_list; +- + #define MAX3421_FIFO_SIZE 64 + + #define MAX3421_SPI_DIR_RD 0 /* read register from MAX3421 */ +@@ -1835,9 +1831,8 @@ max3421_probe(struct spi_device *spi) + } + set_bit(HCD_FLAG_POLL_RH, &hcd->flags); + max3421_hcd = hcd_to_max3421(hcd); +- max3421_hcd->next = max3421_hcd_list; +- max3421_hcd_list = max3421_hcd; + INIT_LIST_HEAD(&max3421_hcd->ep_list); ++ spi_set_drvdata(spi, max3421_hcd); + + max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL); + if (!max3421_hcd->tx) +@@ -1882,28 +1877,18 @@ error: + static int + max3421_remove(struct spi_device *spi) + { +- struct max3421_hcd *max3421_hcd = NULL, **prev; +- struct usb_hcd *hcd = NULL; ++ struct max3421_hcd *max3421_hcd; ++ struct usb_hcd *hcd; + unsigned long flags; + +- for (prev = &max3421_hcd_list; *prev; prev = &(*prev)->next) { +- max3421_hcd = *prev; +- hcd = max3421_to_hcd(max3421_hcd); +- if (hcd->self.controller == &spi->dev) +- break; +- } +- if (!max3421_hcd) { +- dev_err(&spi->dev, "no MAX3421 HCD found for SPI device %p\n", +- spi); +- return -ENODEV; +- } ++ max3421_hcd = spi_get_drvdata(spi); ++ hcd = max3421_to_hcd(max3421_hcd); + + usb_remove_hcd(hcd); + + spin_lock_irqsave(&max3421_hcd->lock, flags); + + kthread_stop(max3421_hcd->spi_thread); +- *prev = max3421_hcd->next; + + spin_unlock_irqrestore(&max3421_hcd->lock, flags); +