mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
ALSA: cs46xx: Allocate resources with device-managed APIs
This patch converts the resource management in PCI cs46xx 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. This should give no user-visible functional changes. Link: https://lore.kernel.org/r/20210715075941.23332-31-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
1656fa6ea2
commit
5bff69b364
@ -66,61 +66,44 @@ static int snd_card_cs46xx_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(*chip), &card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
chip = card->private_data;
|
||||
err = snd_cs46xx_create(card, pci,
|
||||
external_amp[dev], thinkpad[dev],
|
||||
&chip);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
external_amp[dev], thinkpad[dev]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
card->private_data = chip;
|
||||
chip->accept_valid = mmap_valid[dev];
|
||||
err = snd_cs46xx_pcm(chip, 0);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
err = snd_cs46xx_pcm_rear(chip, 1);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
err = snd_cs46xx_pcm_iec958(chip, 2);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
err = snd_cs46xx_mixer(chip, 2);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
if (chip->nr_ac97_codecs ==2) {
|
||||
err = snd_cs46xx_pcm_center_lfe(chip, 3);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
err = snd_cs46xx_midi(chip, 0);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
err = snd_cs46xx_start_dsp(chip);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
snd_cs46xx_gameport(chip);
|
||||
|
||||
@ -133,26 +116,18 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
|
||||
chip->irq);
|
||||
|
||||
err = snd_card_register(card);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
pci_set_drvdata(pci, card);
|
||||
dev++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_card_cs46xx_remove(struct pci_dev *pci)
|
||||
{
|
||||
snd_card_free(pci_get_drvdata(pci));
|
||||
}
|
||||
|
||||
static struct pci_driver cs46xx_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_cs46xx_ids,
|
||||
.probe = snd_card_cs46xx_probe,
|
||||
.remove = snd_card_cs46xx_remove,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.driver = {
|
||||
.pm = &snd_cs46xx_pm,
|
||||
|
@ -1635,7 +1635,6 @@ struct snd_cs46xx_region {
|
||||
unsigned long base;
|
||||
void __iomem *remap_addr;
|
||||
unsigned long size;
|
||||
struct resource *resource;
|
||||
};
|
||||
|
||||
struct snd_cs46xx {
|
||||
@ -1718,8 +1717,7 @@ struct snd_cs46xx {
|
||||
|
||||
int snd_cs46xx_create(struct snd_card *card,
|
||||
struct pci_dev *pci,
|
||||
int external_amp, int thinkpad,
|
||||
struct snd_cs46xx **rcodec);
|
||||
int external_amp, int thinkpad);
|
||||
extern const struct dev_pm_ops snd_cs46xx_pm;
|
||||
|
||||
int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device);
|
||||
|
@ -1865,13 +1865,6 @@ int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device)
|
||||
/*
|
||||
* Mixer routines
|
||||
*/
|
||||
static void snd_cs46xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
|
||||
{
|
||||
struct snd_cs46xx *chip = bus->private_data;
|
||||
|
||||
chip->ac97_bus = NULL;
|
||||
}
|
||||
|
||||
static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97)
|
||||
{
|
||||
struct snd_cs46xx *chip = ac97->private_data;
|
||||
@ -2487,7 +2480,6 @@ int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
|
||||
err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
|
||||
if (err < 0)
|
||||
return err;
|
||||
chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus;
|
||||
|
||||
if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0)
|
||||
return -ENXIO;
|
||||
@ -2913,12 +2905,12 @@ static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip)
|
||||
}
|
||||
|
||||
|
||||
static int snd_cs46xx_free(struct snd_cs46xx *chip)
|
||||
static void snd_cs46xx_free(struct snd_card *card)
|
||||
{
|
||||
struct snd_cs46xx *chip = card->private_data;
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
int idx;
|
||||
|
||||
if (snd_BUG_ON(!chip))
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
if (chip->active_ctrl)
|
||||
chip->active_ctrl(chip, 1);
|
||||
@ -2930,22 +2922,11 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
|
||||
|
||||
snd_cs46xx_proc_done(chip);
|
||||
|
||||
if (chip->region.idx[0].resource)
|
||||
snd_cs46xx_hw_stop(chip);
|
||||
|
||||
if (chip->irq >= 0)
|
||||
free_irq(chip->irq, chip);
|
||||
snd_cs46xx_hw_stop(chip);
|
||||
|
||||
if (chip->active_ctrl)
|
||||
chip->active_ctrl(chip, -chip->amplifier);
|
||||
|
||||
for (idx = 0; idx < 5; idx++) {
|
||||
struct snd_cs46xx_region *region = &chip->region.idx[idx];
|
||||
|
||||
iounmap(region->remap_addr);
|
||||
release_and_free_resource(region->resource);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
if (chip->dsp_spos_instance) {
|
||||
cs46xx_dsp_spos_destroy(chip);
|
||||
@ -2956,20 +2937,6 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
|
||||
#else
|
||||
vfree(chip->ba1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
kfree(chip->saved_regs);
|
||||
#endif
|
||||
|
||||
pci_disable_device(chip->pci);
|
||||
kfree(chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cs46xx_dev_free(struct snd_device *device)
|
||||
{
|
||||
struct snd_cs46xx *chip = device->device_data;
|
||||
return snd_cs46xx_free(chip);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3868,30 +3835,19 @@ SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
|
||||
|
||||
int snd_cs46xx_create(struct snd_card *card,
|
||||
struct pci_dev *pci,
|
||||
int external_amp, int thinkpad,
|
||||
struct snd_cs46xx **rchip)
|
||||
int external_amp, int thinkpad)
|
||||
{
|
||||
struct snd_cs46xx *chip;
|
||||
struct snd_cs46xx *chip = card->private_data;
|
||||
int err, idx;
|
||||
struct snd_cs46xx_region *region;
|
||||
struct cs_card_type *cp;
|
||||
u16 ss_card, ss_vendor;
|
||||
static const struct snd_device_ops ops = {
|
||||
.dev_free = snd_cs46xx_dev_free,
|
||||
};
|
||||
|
||||
*rchip = NULL;
|
||||
|
||||
/* enable PCI device */
|
||||
err = pci_enable_device(pci);
|
||||
err = pcim_enable_device(pci);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
||||
if (chip == NULL) {
|
||||
pci_disable_device(pci);
|
||||
return -ENOMEM;
|
||||
}
|
||||
spin_lock_init(&chip->reg_lock);
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
mutex_init(&chip->spos_mutex);
|
||||
@ -3899,6 +3855,10 @@ int snd_cs46xx_create(struct snd_card *card,
|
||||
chip->card = card;
|
||||
chip->pci = pci;
|
||||
chip->irq = -1;
|
||||
|
||||
err = pci_request_regions(pci, "CS46xx");
|
||||
if (err < 0)
|
||||
return err;
|
||||
chip->ba0_addr = pci_resource_start(pci, 0);
|
||||
chip->ba1_addr = pci_resource_start(pci, 1);
|
||||
if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
|
||||
@ -3906,7 +3866,6 @@ int snd_cs46xx_create(struct snd_card *card,
|
||||
dev_err(chip->card->dev,
|
||||
"wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n",
|
||||
chip->ba0_addr, chip->ba1_addr);
|
||||
snd_cs46xx_free(chip);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -3978,67 +3937,45 @@ int snd_cs46xx_create(struct snd_card *card,
|
||||
|
||||
for (idx = 0; idx < 5; idx++) {
|
||||
region = &chip->region.idx[idx];
|
||||
region->resource = request_mem_region(region->base, region->size,
|
||||
region->name);
|
||||
if (!region->resource) {
|
||||
dev_err(chip->card->dev,
|
||||
"unable to request memory region 0x%lx-0x%lx\n",
|
||||
region->base, region->base + region->size - 1);
|
||||
snd_cs46xx_free(chip);
|
||||
return -EBUSY;
|
||||
}
|
||||
region->remap_addr = ioremap(region->base, region->size);
|
||||
region->remap_addr = devm_ioremap(&pci->dev, region->base,
|
||||
region->size);
|
||||
if (region->remap_addr == NULL) {
|
||||
dev_err(chip->card->dev,
|
||||
"%s ioremap problem\n", region->name);
|
||||
snd_cs46xx_free(chip);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
|
||||
KBUILD_MODNAME, chip)) {
|
||||
if (devm_request_irq(&pci->dev, pci->irq, snd_cs46xx_interrupt,
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_cs46xx_free(chip);
|
||||
return -EBUSY;
|
||||
}
|
||||
chip->irq = pci->irq;
|
||||
card->sync_irq = chip->irq;
|
||||
card->private_free = snd_cs46xx_free;
|
||||
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip);
|
||||
if (chip->dsp_spos_instance == NULL) {
|
||||
snd_cs46xx_free(chip);
|
||||
if (!chip->dsp_spos_instance)
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
err = snd_cs46xx_chip_init(chip);
|
||||
if (err < 0) {
|
||||
snd_cs46xx_free(chip);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
|
||||
if (err < 0) {
|
||||
snd_cs46xx_free(chip);
|
||||
return err;
|
||||
}
|
||||
|
||||
snd_cs46xx_proc_init(card, chip);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
chip->saved_regs = kmalloc_array(ARRAY_SIZE(saved_regs),
|
||||
sizeof(*chip->saved_regs),
|
||||
GFP_KERNEL);
|
||||
if (!chip->saved_regs) {
|
||||
snd_cs46xx_free(chip);
|
||||
chip->saved_regs = devm_kmalloc_array(&pci->dev,
|
||||
ARRAY_SIZE(saved_regs),
|
||||
sizeof(*chip->saved_regs),
|
||||
GFP_KERNEL);
|
||||
if (!chip->saved_regs)
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
chip->active_ctrl(chip, -1); /* disable CLKRUN */
|
||||
|
||||
*rchip = chip;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user