Skip to content

Commit 2393e75

Browse files
committed
ALSA: hda: Release resources at error in delayed probe
snd-hda-intel driver handles the most of its probe task in the delayed work (either via workqueue or via firmware loader). When an error happens in the later delayed probe, we can't deregister the device itself because the probe callback already returned success and the device was bound. So, for now, we set hda->init_failed flag and make the rest untouched until the device gets really unbound. However, this leaves the device up running, keeping the resources without any use that prevents other operations. In this patch, we release the resources at first when a probe error happens in the delayed probe stage, but keeps the top-level object, so that the PM and other ops can still refer to the object itself. Also for simplicity, snd_hda_intel object is allocated via devm, so that we can get rid of the explicit kfree calls. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043 Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 10db5bc commit 2393e75

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

sound/pci/hda/hda_intel.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,10 +1203,8 @@ static void azx_vs_set_state(struct pci_dev *pci,
12031203
if (!disabled) {
12041204
dev_info(chip->card->dev,
12051205
"Start delayed initialization\n");
1206-
if (azx_probe_continue(chip) < 0) {
1206+
if (azx_probe_continue(chip) < 0)
12071207
dev_err(chip->card->dev, "initialization error\n");
1208-
hda->init_failed = true;
1209-
}
12101208
}
12111209
} else {
12121210
dev_info(chip->card->dev, "%s via vga_switcheroo\n",
@@ -1339,12 +1337,15 @@ static int register_vga_switcheroo(struct azx *chip)
13391337
/*
13401338
* destructor
13411339
*/
1342-
static int azx_free(struct azx *chip)
1340+
static void azx_free(struct azx *chip)
13431341
{
13441342
struct pci_dev *pci = chip->pci;
13451343
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
13461344
struct hdac_bus *bus = azx_bus(chip);
13471345

1346+
if (hda->freed)
1347+
return;
1348+
13481349
if (azx_has_pm_runtime(chip) && chip->running)
13491350
pm_runtime_get_noresume(&pci->dev);
13501351
chip->running = 0;
@@ -1388,9 +1389,8 @@ static int azx_free(struct azx *chip)
13881389

13891390
if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT)
13901391
snd_hdac_i915_exit(bus);
1391-
kfree(hda);
13921392

1393-
return 0;
1393+
hda->freed = 1;
13941394
}
13951395

13961396
static int azx_dev_disconnect(struct snd_device *device)
@@ -1406,7 +1406,8 @@ static int azx_dev_disconnect(struct snd_device *device)
14061406

14071407
static int azx_dev_free(struct snd_device *device)
14081408
{
1409-
return azx_free(device->device_data);
1409+
azx_free(device->device_data);
1410+
return 0;
14101411
}
14111412

14121413
#ifdef SUPPORT_VGA_SWITCHEROO
@@ -1773,7 +1774,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
17731774
if (err < 0)
17741775
return err;
17751776

1776-
hda = kzalloc(sizeof(*hda), GFP_KERNEL);
1777+
hda = devm_kzalloc(&pci->dev, sizeof(*hda), GFP_KERNEL);
17771778
if (!hda) {
17781779
pci_disable_device(pci);
17791780
return -ENOMEM;
@@ -1814,7 +1815,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
18141815

18151816
err = azx_bus_init(chip, model[dev]);
18161817
if (err < 0) {
1817-
kfree(hda);
18181818
pci_disable_device(pci);
18191819
return err;
18201820
}
@@ -2340,13 +2340,16 @@ static int azx_probe_continue(struct azx *chip)
23402340
pm_runtime_put_autosuspend(&pci->dev);
23412341

23422342
out_free:
2343-
if (err < 0 || !hda->need_i915_power)
2343+
if (err < 0) {
2344+
azx_free(chip);
2345+
return err;
2346+
}
2347+
2348+
if (!hda->need_i915_power)
23442349
display_power(chip, false);
2345-
if (err < 0)
2346-
hda->init_failed = 1;
23472350
complete_all(&hda->probe_wait);
23482351
to_hda_bus(bus)->bus_probing = 0;
2349-
return err;
2352+
return 0;
23502353
}
23512354

23522355
static void azx_remove(struct pci_dev *pci)

sound/pci/hda/hda_intel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct hda_intel {
2727
unsigned int use_vga_switcheroo:1;
2828
unsigned int vga_switcheroo_registered:1;
2929
unsigned int init_failed:1; /* delayed init failed */
30+
unsigned int freed:1; /* resources already released */
3031

3132
bool need_i915_power:1; /* the hda controller needs i915 power */
3233
};

0 commit comments

Comments
 (0)