[PATCH 1/5] sound/hdac_hdmi: Make jack handling asynchronous
Imre Deak
imre.deak at intel.com
Fri Sep 14 17:03:25 UTC 2018
From: Takashi Iwai <tiwai at suse.de>
---
sound/soc/codecs/hdac_hdmi.c | 49 +++++++++++++++++++++++++++++++++++---------
1 file changed, 39 insertions(+), 10 deletions(-)
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 7b8533abf637..f59dec7ce7af 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -96,8 +96,10 @@ struct hdac_hdmi_port {
hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
struct hdac_hdmi_eld eld;
const char *jack_pin;
+ bool is_connect;
struct snd_soc_dapm_context *dapm;
const char *output_pin;
+ struct work_struct dapm_work;
};
struct hdac_hdmi_pcm {
@@ -158,16 +160,12 @@ hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi,
return pcm;
}
-static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
+static void __hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
struct hdac_hdmi_port *port, bool is_connect)
{
struct hdac_device *hdev = port->pin->hdev;
- if (is_connect)
- snd_soc_dapm_enable_pin(port->dapm, port->jack_pin);
- else
- snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
-
+ port->is_connect = is_connect;
if (is_connect) {
/*
* Report Jack connect event when a device is connected
@@ -193,10 +191,32 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
if (pcm->jack_event > 0)
pcm->jack_event--;
}
+}
+static void hdac_hdmi_port_dapm_update(struct hdac_hdmi_port *port)
+{
+ if (port->is_connect)
+ snd_soc_dapm_enable_pin(port->dapm, port->jack_pin);
+ else
+ snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
snd_soc_dapm_sync(port->dapm);
}
+static void hdac_hdmi_jack_dapm_work(struct work_struct *work)
+{
+ struct hdac_hdmi_port *port;
+
+ port = container_of(work, struct hdac_hdmi_port, dapm_work);
+ hdac_hdmi_port_dapm_update(port);
+}
+
+static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
+ struct hdac_hdmi_port *port, bool is_connect)
+{
+ __hdac_hdmi_jack_report(pcm, port, is_connect);
+ hdac_hdmi_port_dapm_update(port);
+}
+
/* MST supported verbs */
/*
* Get the no devices that can be connected to a port on the Pin widget.
@@ -1261,16 +1281,20 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
* report jack here. It will be done in usermode mux
* control select.
*/
- if (pcm)
- hdac_hdmi_jack_report(pcm, port, false);
+ if (pcm) {
+ __hdac_hdmi_jack_report(pcm, port, false);
+ schedule_work(&port->dapm_work);
+ }
mutex_unlock(&hdmi->pin_mutex);
return;
}
if (port->eld.monitor_present && port->eld.eld_valid) {
- if (pcm)
- hdac_hdmi_jack_report(pcm, port, true);
+ if (pcm) {
+ __hdac_hdmi_jack_report(pcm, port, true);
+ schedule_work(&port->dapm_work);
+ }
print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
port->eld.eld_buffer, port->eld.eld_size, false);
@@ -1299,6 +1323,7 @@ static int hdac_hdmi_add_ports(struct hdac_hdmi_priv *hdmi,
for (i = 0; i < max_ports; i++) {
ports[i].id = i;
ports[i].pin = pin;
+ INIT_WORK(&ports[i].dapm_work, hdac_hdmi_jack_dapm_work);
}
pin->ports = ports;
pin->num_ports = max_ports;
@@ -2062,6 +2087,10 @@ static int hdac_hdmi_dev_remove(struct hdac_device *hdev)
struct hdac_hdmi_port *port, *port_next;
int i;
+ list_for_each_entry(pin, &hdmi->pin_list, head)
+ for (i = 0; i < pin->num_ports; i++)
+ cancel_work_sync(& pin->ports[i].dapm_work);
+
list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) {
pcm->cvt = NULL;
if (list_empty(&pcm->port_list))
--
2.13.2
More information about the Intel-gfx-trybot
mailing list