Skip to content

Commit ee70bac

Browse files
cristiccbroonie
authored andcommitted
ASoC: nau8821: Avoid unnecessary blocking in IRQ handler
The interrupt handler offloads the microphone detection logic to nau8821_jdet_work(), which implies a sleep operation. However, before being able to process any subsequent hotplug event, the interrupt handler needs to wait for any prior scheduled work to complete. Move the sleep out of jdet_work by converting it to a delayed work. This eliminates the undesired blocking in the interrupt handler when attempting to cancel a recently scheduled work item and should help reducing transient input reports that might confuse user-space. Signed-off-by: Cristian Ciocaltea <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 2b4eda7 commit ee70bac

File tree

2 files changed

+13
-11
lines changed

2 files changed

+13
-11
lines changed

sound/soc/codecs/nau8821.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,16 +1104,12 @@ static void nau8821_eject_jack(struct nau8821 *nau8821)
11041104
static void nau8821_jdet_work(struct work_struct *work)
11051105
{
11061106
struct nau8821 *nau8821 =
1107-
container_of(work, struct nau8821, jdet_work);
1107+
container_of(work, struct nau8821, jdet_work.work);
11081108
struct snd_soc_dapm_context *dapm = nau8821->dapm;
11091109
struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
11101110
struct regmap *regmap = nau8821->regmap;
11111111
int jack_status_reg, mic_detected, event = 0, event_mask = 0;
11121112

1113-
snd_soc_component_force_enable_pin(component, "MICBIAS");
1114-
snd_soc_dapm_sync(dapm);
1115-
msleep(20);
1116-
11171113
regmap_read(regmap, NAU8821_R58_I2C_DEVICE_ID, &jack_status_reg);
11181114
mic_detected = !(jack_status_reg & NAU8821_KEYDET);
11191115
if (mic_detected) {
@@ -1146,6 +1142,7 @@ static void nau8821_jdet_work(struct work_struct *work)
11461142
snd_soc_component_disable_pin(component, "MICBIAS");
11471143
snd_soc_dapm_sync(dapm);
11481144
}
1145+
11491146
event_mask |= SND_JACK_HEADSET;
11501147
snd_soc_jack_report(nau8821->jack, event, event_mask);
11511148
}
@@ -1194,6 +1191,7 @@ static irqreturn_t nau8821_interrupt(int irq, void *data)
11941191
{
11951192
struct nau8821 *nau8821 = (struct nau8821 *)data;
11961193
struct regmap *regmap = nau8821->regmap;
1194+
struct snd_soc_component *component;
11971195
int active_irq, event = 0, event_mask = 0;
11981196

11991197
if (regmap_read(regmap, NAU8821_R10_IRQ_STATUS, &active_irq)) {
@@ -1205,7 +1203,7 @@ static irqreturn_t nau8821_interrupt(int irq, void *data)
12051203

12061204
if ((active_irq & NAU8821_JACK_EJECT_IRQ_MASK) ==
12071205
NAU8821_JACK_EJECT_DETECTED) {
1208-
cancel_work_sync(&nau8821->jdet_work);
1206+
cancel_delayed_work_sync(&nau8821->jdet_work);
12091207
regmap_update_bits(regmap, NAU8821_R71_ANALOG_ADC_1,
12101208
NAU8821_MICDET_MASK, NAU8821_MICDET_DIS);
12111209
nau8821_eject_jack(nau8821);
@@ -1219,12 +1217,15 @@ static irqreturn_t nau8821_interrupt(int irq, void *data)
12191217
nau8821_irq_status_clear(regmap, NAU8821_KEY_RELEASE_IRQ);
12201218
} else if ((active_irq & NAU8821_JACK_INSERT_IRQ_MASK) ==
12211219
NAU8821_JACK_INSERT_DETECTED) {
1222-
cancel_work_sync(&nau8821->jdet_work);
1220+
cancel_delayed_work_sync(&nau8821->jdet_work);
12231221
regmap_update_bits(regmap, NAU8821_R71_ANALOG_ADC_1,
12241222
NAU8821_MICDET_MASK, NAU8821_MICDET_EN);
12251223
if (nau8821_is_jack_inserted(regmap)) {
1226-
/* detect microphone and jack type */
1227-
schedule_work(&nau8821->jdet_work);
1224+
/* Detect microphone and jack type */
1225+
component = snd_soc_dapm_to_component(nau8821->dapm);
1226+
snd_soc_component_force_enable_pin(component, "MICBIAS");
1227+
snd_soc_dapm_sync(nau8821->dapm);
1228+
schedule_delayed_work(&nau8821->jdet_work, msecs_to_jiffies(20));
12281229
/* Turn off insertion interruption at manual mode */
12291230
nau8821_setup_inserted_irq(nau8821);
12301231
} else {
@@ -1661,7 +1662,8 @@ int nau8821_enable_jack_detect(struct snd_soc_component *component,
16611662

16621663
nau8821->jack = jack;
16631664
/* Initiate jack detection work queue */
1664-
INIT_WORK(&nau8821->jdet_work, nau8821_jdet_work);
1665+
INIT_DELAYED_WORK(&nau8821->jdet_work, nau8821_jdet_work);
1666+
16651667
ret = devm_request_threaded_irq(nau8821->dev, nau8821->irq, NULL,
16661668
nau8821_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
16671669
"nau8821", nau8821);

sound/soc/codecs/nau8821.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ struct nau8821 {
561561
struct regmap *regmap;
562562
struct snd_soc_dapm_context *dapm;
563563
struct snd_soc_jack *jack;
564-
struct work_struct jdet_work;
564+
struct delayed_work jdet_work;
565565
int irq;
566566
int clk_id;
567567
int micbias_voltage;

0 commit comments

Comments
 (0)