ALSA: cs46xx: Allocate resources with device-managed APIs
authorTakashi Iwai <tiwai@suse.de>
Thu, 15 Jul 2021 07:58:52 +0000 (09:58 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 19 Jul 2021 14:16:54 +0000 (16:16 +0200)
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>
sound/pci/cs46xx/cs46xx.c
sound/pci/cs46xx/cs46xx.h
sound/pci/cs46xx/cs46xx_lib.c

index 358ca84cbdead2934c5443db24c0411f7d19da2f..bd60308769ff7eab6b0da50a72d2e3a6ebe09be6 100644 (file)
@@ -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,
index b275df883d06899a3ff819c116cf6eced0e67e8a..c4f0a0b9427052a4dc68de4233acca8282da2596 100644 (file)
@@ -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);
index 1e1eb17f8e077ebc45de925469d8a2eb80f8cad9..8877afb667042653558b6e244694dc67893d03ad 100644 (file)
@@ -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);
-               return err;
-       }
-
-       err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
-       if (err < 0) {
-               snd_cs46xx_free(chip);
+       if (err < 0)
                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;
 }