| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * tascam.c - a part of driver for TASCAM FireWire series |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2015 Takashi Sakamoto |
|---|
| 5 | | - * |
|---|
| 6 | | - * Licensed under the terms of the GNU General Public License, version 2. |
|---|
| 7 | 6 | */ |
|---|
| 8 | 7 | |
|---|
| 9 | 8 | #include "tascam.h" |
|---|
| .. | .. |
|---|
| 85 | 84 | return 0; |
|---|
| 86 | 85 | } |
|---|
| 87 | 86 | |
|---|
| 88 | | -static void tscm_free(struct snd_tscm *tscm) |
|---|
| 89 | | -{ |
|---|
| 90 | | - snd_tscm_transaction_unregister(tscm); |
|---|
| 91 | | - snd_tscm_stream_destroy_duplex(tscm); |
|---|
| 92 | | - |
|---|
| 93 | | - fw_unit_put(tscm->unit); |
|---|
| 94 | | - |
|---|
| 95 | | - mutex_destroy(&tscm->mutex); |
|---|
| 96 | | - kfree(tscm); |
|---|
| 97 | | -} |
|---|
| 98 | | - |
|---|
| 99 | 87 | static void tscm_card_free(struct snd_card *card) |
|---|
| 100 | 88 | { |
|---|
| 101 | | - tscm_free(card->private_data); |
|---|
| 89 | + struct snd_tscm *tscm = card->private_data; |
|---|
| 90 | + |
|---|
| 91 | + snd_tscm_transaction_unregister(tscm); |
|---|
| 92 | + snd_tscm_stream_destroy_duplex(tscm); |
|---|
| 102 | 93 | } |
|---|
| 103 | 94 | |
|---|
| 104 | 95 | static void do_registration(struct work_struct *work) |
|---|
| .. | .. |
|---|
| 110 | 101 | &tscm->card); |
|---|
| 111 | 102 | if (err < 0) |
|---|
| 112 | 103 | return; |
|---|
| 104 | + tscm->card->private_free = tscm_card_free; |
|---|
| 105 | + tscm->card->private_data = tscm; |
|---|
| 113 | 106 | |
|---|
| 114 | 107 | err = identify_model(tscm); |
|---|
| 115 | 108 | if (err < 0) |
|---|
| .. | .. |
|---|
| 141 | 134 | if (err < 0) |
|---|
| 142 | 135 | goto error; |
|---|
| 143 | 136 | |
|---|
| 144 | | - /* |
|---|
| 145 | | - * After registered, tscm instance can be released corresponding to |
|---|
| 146 | | - * releasing the sound card instance. |
|---|
| 147 | | - */ |
|---|
| 148 | | - tscm->card->private_free = tscm_card_free; |
|---|
| 149 | | - tscm->card->private_data = tscm; |
|---|
| 150 | 137 | tscm->registered = true; |
|---|
| 151 | 138 | |
|---|
| 152 | 139 | return; |
|---|
| 153 | 140 | error: |
|---|
| 154 | | - snd_tscm_transaction_unregister(tscm); |
|---|
| 155 | | - snd_tscm_stream_destroy_duplex(tscm); |
|---|
| 156 | 141 | snd_card_free(tscm->card); |
|---|
| 157 | 142 | dev_info(&tscm->unit->device, |
|---|
| 158 | 143 | "Sound card registration failed: %d\n", err); |
|---|
| .. | .. |
|---|
| 164 | 149 | struct snd_tscm *tscm; |
|---|
| 165 | 150 | |
|---|
| 166 | 151 | /* Allocate this independent of sound card instance. */ |
|---|
| 167 | | - tscm = kzalloc(sizeof(struct snd_tscm), GFP_KERNEL); |
|---|
| 168 | | - if (tscm == NULL) |
|---|
| 152 | + tscm = devm_kzalloc(&unit->device, sizeof(struct snd_tscm), GFP_KERNEL); |
|---|
| 153 | + if (!tscm) |
|---|
| 169 | 154 | return -ENOMEM; |
|---|
| 170 | | - |
|---|
| 171 | | - /* initialize myself */ |
|---|
| 172 | 155 | tscm->unit = fw_unit_get(unit); |
|---|
| 173 | 156 | dev_set_drvdata(&unit->device, tscm); |
|---|
| 174 | 157 | |
|---|
| .. | .. |
|---|
| 216 | 199 | cancel_delayed_work_sync(&tscm->dwork); |
|---|
| 217 | 200 | |
|---|
| 218 | 201 | if (tscm->registered) { |
|---|
| 219 | | - /* No need to wait for releasing card object in this context. */ |
|---|
| 220 | | - snd_card_free_when_closed(tscm->card); |
|---|
| 221 | | - } else { |
|---|
| 222 | | - /* Don't forget this case. */ |
|---|
| 223 | | - tscm_free(tscm); |
|---|
| 202 | + // Block till all of ALSA character devices are released. |
|---|
| 203 | + snd_card_free(tscm->card); |
|---|
| 224 | 204 | } |
|---|
| 205 | + |
|---|
| 206 | + mutex_destroy(&tscm->mutex); |
|---|
| 207 | + fw_unit_put(tscm->unit); |
|---|
| 225 | 208 | } |
|---|
| 226 | 209 | |
|---|
| 227 | 210 | static const struct ieee1394_device_id snd_tscm_id_table[] = { |
|---|
| .. | .. |
|---|
| 259 | 242 | .specifier_id = 0x00022e, |
|---|
| 260 | 243 | .version = 0x800004, |
|---|
| 261 | 244 | }, |
|---|
| 262 | | - /* FE-08 requires reverse-engineering because it just has faders. */ |
|---|
| 263 | 245 | {} |
|---|
| 264 | 246 | }; |
|---|
| 265 | 247 | MODULE_DEVICE_TABLE(ieee1394, snd_tscm_id_table); |
|---|
| .. | .. |
|---|
| 267 | 249 | static struct fw_driver tscm_driver = { |
|---|
| 268 | 250 | .driver = { |
|---|
| 269 | 251 | .owner = THIS_MODULE, |
|---|
| 270 | | - .name = "snd-firewire-tascam", |
|---|
| 252 | + .name = KBUILD_MODNAME, |
|---|
| 271 | 253 | .bus = &fw_bus_type, |
|---|
| 272 | 254 | }, |
|---|
| 273 | 255 | .probe = snd_tscm_probe, |
|---|