ALSA: cs5535audio: Allocate resources with device-managed APIs
This patch converts the resource management in PCI cs5535audio driver with devres as a clean up. Each manual resource management is converted with the corresponding devres helper, and the card object release is managed now via card->private_free instead of a lowlevel snd_device. A slight uncertain change is the call of olpc_quirks_cleanup() at removal: formerly this was called unconditionally at remove, but this should be a conditionally call, hence the machine_is_olpc() check is added here as well. This should give no user-visible functional changes. Link: https://lore.kernel.org/r/20210715075941.23332-32-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
5bff69b364
commit
5eba4c646d
|
@ -237,51 +237,24 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int snd_cs5535audio_free(struct cs5535audio *cs5535au)
|
||||
static void snd_cs5535audio_free(struct snd_card *card)
|
||||
{
|
||||
pci_set_power_state(cs5535au->pci, PCI_D3hot);
|
||||
|
||||
if (cs5535au->irq >= 0)
|
||||
free_irq(cs5535au->irq, cs5535au);
|
||||
|
||||
pci_release_regions(cs5535au->pci);
|
||||
pci_disable_device(cs5535au->pci);
|
||||
kfree(cs5535au);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cs5535audio_dev_free(struct snd_device *device)
|
||||
{
|
||||
struct cs5535audio *cs5535au = device->device_data;
|
||||
return snd_cs5535audio_free(cs5535au);
|
||||
olpc_quirks_cleanup();
|
||||
}
|
||||
|
||||
static int snd_cs5535audio_create(struct snd_card *card,
|
||||
struct pci_dev *pci,
|
||||
struct cs5535audio **rcs5535au)
|
||||
struct pci_dev *pci)
|
||||
{
|
||||
struct cs5535audio *cs5535au;
|
||||
|
||||
struct cs5535audio *cs5535au = card->private_data;
|
||||
int err;
|
||||
static const struct snd_device_ops ops = {
|
||||
.dev_free = snd_cs5535audio_dev_free,
|
||||
};
|
||||
|
||||
*rcs5535au = NULL;
|
||||
err = pci_enable_device(pci);
|
||||
err = pcim_enable_device(pci);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) {
|
||||
dev_warn(card->dev, "unable to get 32bit dma\n");
|
||||
err = -ENXIO;
|
||||
goto pcifail;
|
||||
}
|
||||
|
||||
cs5535au = kzalloc(sizeof(*cs5535au), GFP_KERNEL);
|
||||
if (cs5535au == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto pcifail;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
spin_lock_init(&cs5535au->reg_lock);
|
||||
|
@ -290,38 +263,22 @@ static int snd_cs5535audio_create(struct snd_card *card,
|
|||
cs5535au->irq = -1;
|
||||
|
||||
err = pci_request_regions(pci, "CS5535 Audio");
|
||||
if (err < 0) {
|
||||
kfree(cs5535au);
|
||||
goto pcifail;
|
||||
}
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cs5535au->port = pci_resource_start(pci, 0);
|
||||
|
||||
if (request_irq(pci->irq, snd_cs5535audio_interrupt,
|
||||
IRQF_SHARED, KBUILD_MODNAME, cs5535au)) {
|
||||
if (devm_request_irq(&pci->dev, pci->irq, snd_cs5535audio_interrupt,
|
||||
IRQF_SHARED, KBUILD_MODNAME, cs5535au)) {
|
||||
dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
|
||||
err = -EBUSY;
|
||||
goto sndfail;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
cs5535au->irq = pci->irq;
|
||||
card->sync_irq = cs5535au->irq;
|
||||
pci_set_master(pci);
|
||||
|
||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cs5535au, &ops);
|
||||
if (err < 0)
|
||||
goto sndfail;
|
||||
|
||||
*rcs5535au = cs5535au;
|
||||
return 0;
|
||||
|
||||
sndfail: /* leave the device alive, just kill the snd */
|
||||
snd_cs5535audio_free(cs5535au);
|
||||
return err;
|
||||
|
||||
pcifail:
|
||||
pci_disable_device(pci);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int snd_cs5535audio_probe(struct pci_dev *pci,
|
||||
|
@ -339,24 +296,24 @@ static int snd_cs5535audio_probe(struct pci_dev *pci,
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
|
||||
0, &card);
|
||||
err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
|
||||
sizeof(*cs5535au), &card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
cs5535au = card->private_data;
|
||||
card->private_free = snd_cs5535audio_free;
|
||||
|
||||
err = snd_cs5535audio_create(card, pci);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_cs5535audio_create(card, pci, &cs5535au);
|
||||
if (err < 0)
|
||||
goto probefail_out;
|
||||
|
||||
card->private_data = cs5535au;
|
||||
|
||||
err = snd_cs5535audio_mixer(cs5535au);
|
||||
if (err < 0)
|
||||
goto probefail_out;
|
||||
return err;
|
||||
|
||||
err = snd_cs5535audio_pcm(cs5535au);
|
||||
if (err < 0)
|
||||
goto probefail_out;
|
||||
return err;
|
||||
|
||||
strcpy(card->driver, DRIVER_NAME);
|
||||
|
||||
|
@ -367,28 +324,17 @@ static int snd_cs5535audio_probe(struct pci_dev *pci,
|
|||
|
||||
err = snd_card_register(card);
|
||||
if (err < 0)
|
||||
goto probefail_out;
|
||||
return err;
|
||||
|
||||
pci_set_drvdata(pci, card);
|
||||
dev++;
|
||||
return 0;
|
||||
|
||||
probefail_out:
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void snd_cs5535audio_remove(struct pci_dev *pci)
|
||||
{
|
||||
olpc_quirks_cleanup();
|
||||
snd_card_free(pci_get_drvdata(pci));
|
||||
}
|
||||
|
||||
static struct pci_driver cs5535audio_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_cs5535audio_ids,
|
||||
.probe = snd_cs5535audio_probe,
|
||||
.remove = snd_cs5535audio_remove,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.driver = {
|
||||
.pm = &snd_cs5535audio_pm,
|
||||
|
|
|
@ -171,10 +171,8 @@ int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
|
|||
for (i = 0; i < ARRAY_SIZE(olpc_cs5535audio_ctls); i++) {
|
||||
err = snd_ctl_add(card, snd_ctl_new1(&olpc_cs5535audio_ctls[i],
|
||||
ac97->private_data));
|
||||
if (err < 0) {
|
||||
gpio_free(OLPC_GPIO_MIC_AC);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* turn off the mic by default */
|
||||
|
@ -184,5 +182,6 @@ int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
|
|||
|
||||
void olpc_quirks_cleanup(void)
|
||||
{
|
||||
gpio_free(OLPC_GPIO_MIC_AC);
|
||||
if (machine_is_olpc())
|
||||
gpio_free(OLPC_GPIO_MIC_AC);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue