Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+38 -128
+13 -38
sound/pci/cs46xx/cs46xx.c
··· 66 66 return -ENOENT; 67 67 } 68 68 69 - err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, 70 - 0, &card); 69 + err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, 70 + sizeof(*chip), &card); 71 71 if (err < 0) 72 72 return err; 73 + chip = card->private_data; 73 74 err = snd_cs46xx_create(card, pci, 74 - external_amp[dev], thinkpad[dev], 75 - &chip); 76 - if (err < 0) { 77 - snd_card_free(card); 75 + external_amp[dev], thinkpad[dev]); 76 + if (err < 0) 78 77 return err; 79 - } 80 78 card->private_data = chip; 81 79 chip->accept_valid = mmap_valid[dev]; 82 80 err = snd_cs46xx_pcm(chip, 0); 83 - if (err < 0) { 84 - snd_card_free(card); 81 + if (err < 0) 85 82 return err; 86 - } 87 83 #ifdef CONFIG_SND_CS46XX_NEW_DSP 88 84 err = snd_cs46xx_pcm_rear(chip, 1); 89 - if (err < 0) { 90 - snd_card_free(card); 85 + if (err < 0) 91 86 return err; 92 - } 93 87 err = snd_cs46xx_pcm_iec958(chip, 2); 94 - if (err < 0) { 95 - snd_card_free(card); 88 + if (err < 0) 96 89 return err; 97 - } 98 90 #endif 99 91 err = snd_cs46xx_mixer(chip, 2); 100 - if (err < 0) { 101 - snd_card_free(card); 92 + if (err < 0) 102 93 return err; 103 - } 104 94 #ifdef CONFIG_SND_CS46XX_NEW_DSP 105 95 if (chip->nr_ac97_codecs ==2) { 106 96 err = snd_cs46xx_pcm_center_lfe(chip, 3); 107 - if (err < 0) { 108 - snd_card_free(card); 97 + if (err < 0) 109 98 return err; 110 - } 111 99 } 112 100 #endif 113 101 err = snd_cs46xx_midi(chip, 0); 114 - if (err < 0) { 115 - snd_card_free(card); 102 + if (err < 0) 116 103 return err; 117 - } 118 104 err = snd_cs46xx_start_dsp(chip); 119 - if (err < 0) { 120 - snd_card_free(card); 105 + if (err < 0) 121 106 return err; 122 - } 123 - 124 107 125 108 snd_cs46xx_gameport(chip); 126 109 ··· 116 133 chip->irq); 117 134 118 135 err = snd_card_register(card); 119 - if (err < 0) { 120 - snd_card_free(card); 136 + if (err < 0) 121 137 return err; 122 - } 123 138 124 139 pci_set_drvdata(pci, card); 125 140 dev++; 126 141 return 0; 127 142 } 128 143 129 - static void snd_card_cs46xx_remove(struct pci_dev *pci) 130 - { 131 - snd_card_free(pci_get_drvdata(pci)); 132 - } 133 - 134 144 static struct pci_driver cs46xx_driver = { 135 145 .name = KBUILD_MODNAME, 136 146 .id_table = snd_cs46xx_ids, 137 147 .probe = snd_card_cs46xx_probe, 138 - .remove = snd_card_cs46xx_remove, 139 148 #ifdef CONFIG_PM_SLEEP 140 149 .driver = { 141 150 .pm = &snd_cs46xx_pm,
+1 -3
sound/pci/cs46xx/cs46xx.h
··· 1635 1635 unsigned long base; 1636 1636 void __iomem *remap_addr; 1637 1637 unsigned long size; 1638 - struct resource *resource; 1639 1638 }; 1640 1639 1641 1640 struct snd_cs46xx { ··· 1717 1718 1718 1719 int snd_cs46xx_create(struct snd_card *card, 1719 1720 struct pci_dev *pci, 1720 - int external_amp, int thinkpad, 1721 - struct snd_cs46xx **rcodec); 1721 + int external_amp, int thinkpad); 1722 1722 extern const struct dev_pm_ops snd_cs46xx_pm; 1723 1723 1724 1724 int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device);
+24 -87
sound/pci/cs46xx/cs46xx_lib.c
··· 1865 1865 /* 1866 1866 * Mixer routines 1867 1867 */ 1868 - static void snd_cs46xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus) 1869 - { 1870 - struct snd_cs46xx *chip = bus->private_data; 1871 - 1872 - chip->ac97_bus = NULL; 1873 - } 1874 - 1875 1868 static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97) 1876 1869 { 1877 1870 struct snd_cs46xx *chip = ac97->private_data; ··· 2480 2487 err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus); 2481 2488 if (err < 0) 2482 2489 return err; 2483 - chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus; 2484 2490 2485 2491 if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0) 2486 2492 return -ENXIO; ··· 2905 2913 } 2906 2914 2907 2915 2908 - static int snd_cs46xx_free(struct snd_cs46xx *chip) 2916 + static void snd_cs46xx_free(struct snd_card *card) 2909 2917 { 2918 + struct snd_cs46xx *chip = card->private_data; 2919 + #ifdef CONFIG_SND_CS46XX_NEW_DSP 2910 2920 int idx; 2911 - 2912 - if (snd_BUG_ON(!chip)) 2913 - return -EINVAL; 2921 + #endif 2914 2922 2915 2923 if (chip->active_ctrl) 2916 2924 chip->active_ctrl(chip, 1); ··· 2922 2930 2923 2931 snd_cs46xx_proc_done(chip); 2924 2932 2925 - if (chip->region.idx[0].resource) 2926 - snd_cs46xx_hw_stop(chip); 2927 - 2928 - if (chip->irq >= 0) 2929 - free_irq(chip->irq, chip); 2933 + snd_cs46xx_hw_stop(chip); 2930 2934 2931 2935 if (chip->active_ctrl) 2932 2936 chip->active_ctrl(chip, -chip->amplifier); 2933 - 2934 - for (idx = 0; idx < 5; idx++) { 2935 - struct snd_cs46xx_region *region = &chip->region.idx[idx]; 2936 - 2937 - iounmap(region->remap_addr); 2938 - release_and_free_resource(region->resource); 2939 - } 2940 2937 2941 2938 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2942 2939 if (chip->dsp_spos_instance) { ··· 2937 2956 #else 2938 2957 vfree(chip->ba1); 2939 2958 #endif 2940 - 2941 - #ifdef CONFIG_PM_SLEEP 2942 - kfree(chip->saved_regs); 2943 - #endif 2944 - 2945 - pci_disable_device(chip->pci); 2946 - kfree(chip); 2947 - return 0; 2948 - } 2949 - 2950 - static int snd_cs46xx_dev_free(struct snd_device *device) 2951 - { 2952 - struct snd_cs46xx *chip = device->device_data; 2953 - return snd_cs46xx_free(chip); 2954 2959 } 2955 2960 2956 2961 /* ··· 3835 3868 3836 3869 int snd_cs46xx_create(struct snd_card *card, 3837 3870 struct pci_dev *pci, 3838 - int external_amp, int thinkpad, 3839 - struct snd_cs46xx **rchip) 3871 + int external_amp, int thinkpad) 3840 3872 { 3841 - struct snd_cs46xx *chip; 3873 + struct snd_cs46xx *chip = card->private_data; 3842 3874 int err, idx; 3843 3875 struct snd_cs46xx_region *region; 3844 3876 struct cs_card_type *cp; 3845 3877 u16 ss_card, ss_vendor; 3846 - static const struct snd_device_ops ops = { 3847 - .dev_free = snd_cs46xx_dev_free, 3848 - }; 3849 3878 3850 - *rchip = NULL; 3851 - 3852 3879 /* enable PCI device */ 3853 - err = pci_enable_device(pci); 3880 + err = pcim_enable_device(pci); 3854 3881 if (err < 0) 3855 3882 return err; 3856 3883 3857 - chip = kzalloc(sizeof(*chip), GFP_KERNEL); 3858 - if (chip == NULL) { 3859 - pci_disable_device(pci); 3860 - return -ENOMEM; 3861 - } 3862 3884 spin_lock_init(&chip->reg_lock); 3863 3885 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3864 3886 mutex_init(&chip->spos_mutex); ··· 3855 3899 chip->card = card; 3856 3900 chip->pci = pci; 3857 3901 chip->irq = -1; 3902 + 3903 + err = pci_request_regions(pci, "CS46xx"); 3904 + if (err < 0) 3905 + return err; 3858 3906 chip->ba0_addr = pci_resource_start(pci, 0); 3859 3907 chip->ba1_addr = pci_resource_start(pci, 1); 3860 3908 if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || ··· 3866 3906 dev_err(chip->card->dev, 3867 3907 "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", 3868 3908 chip->ba0_addr, chip->ba1_addr); 3869 - snd_cs46xx_free(chip); 3870 3909 return -ENOMEM; 3871 3910 } 3872 3911 ··· 3937 3978 3938 3979 for (idx = 0; idx < 5; idx++) { 3939 3980 region = &chip->region.idx[idx]; 3940 - region->resource = request_mem_region(region->base, region->size, 3941 - region->name); 3942 - if (!region->resource) { 3943 - dev_err(chip->card->dev, 3944 - "unable to request memory region 0x%lx-0x%lx\n", 3945 - region->base, region->base + region->size - 1); 3946 - snd_cs46xx_free(chip); 3947 - return -EBUSY; 3948 - } 3949 - region->remap_addr = ioremap(region->base, region->size); 3981 + region->remap_addr = devm_ioremap(&pci->dev, region->base, 3982 + region->size); 3950 3983 if (region->remap_addr == NULL) { 3951 3984 dev_err(chip->card->dev, 3952 3985 "%s ioremap problem\n", region->name); 3953 - snd_cs46xx_free(chip); 3954 3986 return -ENOMEM; 3955 3987 } 3956 3988 } 3957 3989 3958 - if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED, 3959 - KBUILD_MODNAME, chip)) { 3990 + if (devm_request_irq(&pci->dev, pci->irq, snd_cs46xx_interrupt, 3991 + IRQF_SHARED, KBUILD_MODNAME, chip)) { 3960 3992 dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq); 3961 - snd_cs46xx_free(chip); 3962 3993 return -EBUSY; 3963 3994 } 3964 3995 chip->irq = pci->irq; 3965 3996 card->sync_irq = chip->irq; 3997 + card->private_free = snd_cs46xx_free; 3966 3998 3967 3999 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3968 4000 chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip); 3969 - if (chip->dsp_spos_instance == NULL) { 3970 - snd_cs46xx_free(chip); 4001 + if (!chip->dsp_spos_instance) 3971 4002 return -ENOMEM; 3972 - } 3973 4003 #endif 3974 4004 3975 4005 err = snd_cs46xx_chip_init(chip); 3976 - if (err < 0) { 3977 - snd_cs46xx_free(chip); 4006 + if (err < 0) 3978 4007 return err; 3979 - } 3980 - 3981 - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); 3982 - if (err < 0) { 3983 - snd_cs46xx_free(chip); 3984 - return err; 3985 - } 3986 4008 3987 4009 snd_cs46xx_proc_init(card, chip); 3988 4010 3989 4011 #ifdef CONFIG_PM_SLEEP 3990 - chip->saved_regs = kmalloc_array(ARRAY_SIZE(saved_regs), 3991 - sizeof(*chip->saved_regs), 3992 - GFP_KERNEL); 3993 - if (!chip->saved_regs) { 3994 - snd_cs46xx_free(chip); 4012 + chip->saved_regs = devm_kmalloc_array(&pci->dev, 4013 + ARRAY_SIZE(saved_regs), 4014 + sizeof(*chip->saved_regs), 4015 + GFP_KERNEL); 4016 + if (!chip->saved_regs) 3995 4017 return -ENOMEM; 3996 - } 3997 4018 #endif 3998 4019 3999 4020 chip->active_ctrl(chip, -1); /* disable CLKRUN */ 4000 - 4001 - *rchip = chip; 4002 4021 return 0; 4003 4022 }