sunxi-6.16: Fix ASoC: soc-core, usb: dwc3, drm: sun4i

This commit is contained in:
The-going 2025-09-19 07:17:50 +03:00
parent 73c0d635a4
commit eb8b85f63e
3 changed files with 280 additions and 0 deletions

View File

@ -0,0 +1,80 @@
From f79f3df0f61a6c7bdc08e2318cb3f33398f50442 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megi@xff.cz>
Date: Fri, 8 Aug 2025 17:54:21 +0200
Subject: [PATCH 1/3] Revert "ASoC: soc-core: merge
snd_soc_unregister_component() and snd_soc_unregister_component_by_driver()"
This reverts commit 144d6dfc7482455eabf8e8caa974a6e8d9572705.
---
include/sound/soc.h | 2 +-
sound/soc/soc-core.c | 30 +++++++++++++++++++++++++-----
2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 1fffef311c41..8d113ee8c2bc 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -444,7 +444,7 @@ int snd_soc_register_component(struct device *dev,
int devm_snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *component_driver,
struct snd_soc_dai_driver *dai_drv, int num_dai);
-#define snd_soc_unregister_component(dev) snd_soc_unregister_component_by_driver(dev, NULL)
+void snd_soc_unregister_component(struct device *dev);
void snd_soc_unregister_component_by_driver(struct device *dev,
const struct snd_soc_component_driver *component_driver);
struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 67bebc339148..ab615ec113d2 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2927,14 +2927,34 @@ EXPORT_SYMBOL_GPL(snd_soc_register_component);
void snd_soc_unregister_component_by_driver(struct device *dev,
const struct snd_soc_component_driver *component_driver)
{
- const char *driver_name = NULL;
+ struct snd_soc_component *component;
- if (component_driver)
- driver_name = component_driver->name;
+ if (!component_driver)
+ return;
+ mutex_lock(&client_mutex);
+ component = snd_soc_lookup_component_nolocked(dev, component_driver->name);
+ if (!component)
+ goto out;
+
+ snd_soc_del_component_unlocked(component);
+
+out:
+ mutex_unlock(&client_mutex);
+}
+EXPORT_SYMBOL_GPL(snd_soc_unregister_component_by_driver);
+
+/**
+ * snd_soc_unregister_component - Unregister all related component
+ * from the ASoC core
+ *
+ * @dev: The device to unregister
+ */
+void snd_soc_unregister_component(struct device *dev)
+{
mutex_lock(&client_mutex);
while (1) {
- struct snd_soc_component *component = snd_soc_lookup_component_nolocked(dev, driver_name);
+ struct snd_soc_component *component = snd_soc_lookup_component_nolocked(dev, NULL);
if (!component)
break;
@@ -2943,7 +2963,7 @@ void snd_soc_unregister_component_by_driver(struct device *dev,
}
mutex_unlock(&client_mutex);
}
-EXPORT_SYMBOL_GPL(snd_soc_unregister_component_by_driver);
+EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
/* Retrieve a card's name from device tree */
int snd_soc_of_parse_card_name(struct snd_soc_card *card,
--
2.51.0

View File

@ -0,0 +1,89 @@
From 48c707b5f50a1cd87925a725e5c85ac06b19219f Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megi@xff.cz>
Date: Sat, 9 Aug 2025 10:10:42 +0200
Subject: [PATCH 2/3] Revert "usb: dwc3: Abort suspend on soft disconnect
failure"
This reverts commit 630a1dec3b0eba2a695b9063f1c205d585cbfec9.
---
drivers/usb/dwc3/core.c | 9 ++-------
drivers/usb/dwc3/gadget.c | 22 +++++++++++++---------
2 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 91dec9c81a40..1e436ac6a1fa 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -2460,7 +2460,6 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
{
u32 reg;
int i;
- int ret;
if (!pm_runtime_suspended(dwc->dev) && !PMSG_IS_AUTO(msg)) {
dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) &
@@ -2480,9 +2479,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
case DWC3_GCTL_PRTCAP_DEVICE_DISCONNECTED:
if (pm_runtime_suspended(dwc->dev))
break;
- ret = dwc3_gadget_suspend(dwc);
- if (ret)
- return ret;
+ dwc3_gadget_suspend(dwc);
synchronize_irq(dwc->irq_gadget);
dwc3_core_exit(dwc);
break;
@@ -2517,9 +2514,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
break;
if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
- ret = dwc3_gadget_suspend(dwc);
- if (ret)
- return ret;
+ dwc3_gadget_suspend(dwc);
synchronize_irq(dwc->irq_gadget);
}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 74968f93d4a3..99fbd29d8f46 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -4821,15 +4821,8 @@ int dwc3_gadget_suspend(struct dwc3 *dwc)
int ret;
ret = dwc3_gadget_soft_disconnect(dwc);
- /*
- * Attempt to reset the controller's state. Likely no
- * communication can be established until the host
- * performs a port reset.
- */
- if (ret && dwc->softconnect) {
- dwc3_gadget_soft_connect(dwc);
- return -EAGAIN;
- }
+ if (ret)
+ goto err;
spin_lock_irqsave(&dwc->lock, flags);
if (dwc->gadget_driver)
@@ -4837,6 +4830,17 @@ int dwc3_gadget_suspend(struct dwc3 *dwc)
spin_unlock_irqrestore(&dwc->lock, flags);
return 0;
+
+err:
+ /*
+ * Attempt to reset the controller's state. Likely no
+ * communication can be established until the host
+ * performs a port reset.
+ */
+ if (dwc->softconnect)
+ dwc3_gadget_soft_connect(dwc);
+
+ return ret;
}
int dwc3_gadget_resume(struct dwc3 *dwc)
--
2.51.0

View File

@ -0,0 +1,111 @@
From aeb99ba3659e8147e9f01a5ddfd529f1e1b16358 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megi@xff.cz>
Date: Sat, 9 Aug 2025 14:47:14 +0200
Subject: [PATCH 3/3] drm: sun4i: Report page flip after vsync is complete, not
in the middle
See: https://xnux.eu/log/080.html
Signed-off-by: Ondrej Jirman <megi@xff.cz>
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 26 ++++++++++++++++++++++++--
drivers/gpu/drm/sun4i/sun4i_tcon.h | 4 ++++
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 221df37406d8..25c8bff308f2 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -240,6 +240,9 @@ void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable)
if (enable)
val = mask;
+ if (!enable && tcon->quirks->vblank_delay)
+ hrtimer_cancel(&tcon->flip_timer);
+
regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG, mask, val);
}
EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
@@ -838,6 +841,17 @@ static void sun4i_tcon_finish_page_flip(struct drm_device *dev,
spin_unlock_irqrestore(&dev->event_lock, flags);
}
+static enum hrtimer_restart sun4i_tcon_flip_timer_cb(struct hrtimer *timer)
+{
+ struct sun4i_tcon *tcon = container_of(timer,
+ struct sun4i_tcon, flip_timer);
+
+ drm_crtc_handle_vblank(&tcon->crtc->crtc);
+ sun4i_tcon_finish_page_flip(tcon->drm, tcon->crtc);
+
+ return HRTIMER_NORESTART;
+}
+
static irqreturn_t sun4i_tcon_handler(int irq, void *private)
{
struct sun4i_tcon *tcon = private;
@@ -853,8 +867,12 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private)
SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT)))
return IRQ_NONE;
- drm_crtc_handle_vblank(&scrtc->crtc);
- sun4i_tcon_finish_page_flip(drm, scrtc);
+ if (tcon->quirks->vblank_delay) {
+ hrtimer_start(&tcon->flip_timer, us_to_ktime(250), HRTIMER_MODE_REL);
+ } else {
+ drm_crtc_handle_vblank(&scrtc->crtc);
+ sun4i_tcon_finish_page_flip(drm, scrtc);
+ }
/* Acknowledge the interrupt */
regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG,
@@ -903,6 +921,9 @@ static int sun4i_tcon_init_irq(struct device *dev,
struct platform_device *pdev = to_platform_device(dev);
int irq, ret;
+ hrtimer_setup(&tcon->flip_timer, sun4i_tcon_flip_timer_cb,
+ CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
@@ -1616,6 +1637,7 @@ static const struct sun4i_tcon_quirks sun50i_a64_lcd_quirks = {
.restores_rate = true,
.dclk_min_div = 1,
.setup_lvds_phy = sun6i_tcon_setup_lvds_phy,
+ .vblank_delay = true,
};
static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index 729d64b78846..2bf91fb4872c 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -12,6 +12,7 @@
#include <drm/drm_crtc.h>
+#include <linux/hrtimer.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mod_devicetable.h>
@@ -252,6 +253,8 @@ struct sun4i_tcon_quirks {
bool polarity_in_ch0; /* some tcon1 channels have polarity bits in tcon0 pol register */
bool restores_rate; /* restores the initial rate when rate changes */
u8 dclk_min_div; /* minimum divider for TCON0 DCLK */
+ bool vblank_delay; /* delay page flip reporting for 250us (TCON report vblank
+ shortly before register flip) */
/* callback to handle tcon muxing options */
int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
@@ -289,6 +292,7 @@ struct sun4i_tcon {
/* Associated crtc */
struct sun4i_crtc *crtc;
+ struct hrtimer flip_timer;
int id;
--
2.51.0