| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * ALSA sequencer Timer |
|---|
| 3 | 4 | * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl> |
|---|
| 4 | 5 | * Jaroslav Kysela <perex@perex.cz> |
|---|
| 5 | | - * |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 9 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 10 | | - * (at your option) any later version. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | | - * GNU General Public License for more details. |
|---|
| 16 | | - * |
|---|
| 17 | | - * You should have received a copy of the GNU General Public License |
|---|
| 18 | | - * along with this program; if not, write to the Free Software |
|---|
| 19 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 20 | | - * |
|---|
| 21 | 6 | */ |
|---|
| 22 | 7 | |
|---|
| 23 | 8 | #include <sound/core.h> |
|---|
| .. | .. |
|---|
| 287 | 272 | return -EINVAL; |
|---|
| 288 | 273 | if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE) |
|---|
| 289 | 274 | tmr->alsa_id.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER; |
|---|
| 290 | | - err = snd_timer_open(&t, str, &tmr->alsa_id, q->queue); |
|---|
| 275 | + t = snd_timer_instance_new(str); |
|---|
| 276 | + if (!t) |
|---|
| 277 | + return -ENOMEM; |
|---|
| 278 | + t->callback = snd_seq_timer_interrupt; |
|---|
| 279 | + t->callback_data = q; |
|---|
| 280 | + t->flags |= SNDRV_TIMER_IFLG_AUTO; |
|---|
| 281 | + err = snd_timer_open(t, &tmr->alsa_id, q->queue); |
|---|
| 291 | 282 | if (err < 0 && tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE) { |
|---|
| 292 | 283 | if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_GLOBAL || |
|---|
| 293 | 284 | tmr->alsa_id.device != SNDRV_TIMER_GLOBAL_SYSTEM) { |
|---|
| .. | .. |
|---|
| 297 | 288 | tid.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER; |
|---|
| 298 | 289 | tid.card = -1; |
|---|
| 299 | 290 | tid.device = SNDRV_TIMER_GLOBAL_SYSTEM; |
|---|
| 300 | | - err = snd_timer_open(&t, str, &tid, q->queue); |
|---|
| 291 | + err = snd_timer_open(t, &tid, q->queue); |
|---|
| 301 | 292 | } |
|---|
| 302 | 293 | } |
|---|
| 303 | 294 | if (err < 0) { |
|---|
| 304 | 295 | pr_err("ALSA: seq fatal error: cannot create timer (%i)\n", err); |
|---|
| 296 | + snd_timer_instance_free(t); |
|---|
| 305 | 297 | return err; |
|---|
| 306 | 298 | } |
|---|
| 307 | | - t->callback = snd_seq_timer_interrupt; |
|---|
| 308 | | - t->callback_data = q; |
|---|
| 309 | | - t->flags |= SNDRV_TIMER_IFLG_AUTO; |
|---|
| 310 | 299 | spin_lock_irq(&tmr->lock); |
|---|
| 311 | | - tmr->timeri = t; |
|---|
| 300 | + if (tmr->timeri) |
|---|
| 301 | + err = -EBUSY; |
|---|
| 302 | + else |
|---|
| 303 | + tmr->timeri = t; |
|---|
| 312 | 304 | spin_unlock_irq(&tmr->lock); |
|---|
| 305 | + if (err < 0) { |
|---|
| 306 | + snd_timer_close(t); |
|---|
| 307 | + snd_timer_instance_free(t); |
|---|
| 308 | + return err; |
|---|
| 309 | + } |
|---|
| 313 | 310 | return 0; |
|---|
| 314 | 311 | } |
|---|
| 315 | 312 | |
|---|
| .. | .. |
|---|
| 325 | 322 | t = tmr->timeri; |
|---|
| 326 | 323 | tmr->timeri = NULL; |
|---|
| 327 | 324 | spin_unlock_irq(&tmr->lock); |
|---|
| 328 | | - if (t) |
|---|
| 325 | + if (t) { |
|---|
| 329 | 326 | snd_timer_close(t); |
|---|
| 327 | + snd_timer_instance_free(t); |
|---|
| 328 | + } |
|---|
| 330 | 329 | return 0; |
|---|
| 331 | 330 | } |
|---|
| 332 | 331 | |
|---|