| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Edirol UA-101/UA-1000 driver |
|---|
| 3 | 4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> |
|---|
| 4 | | - * |
|---|
| 5 | | - * This driver is free software: you can redistribute it and/or modify |
|---|
| 6 | | - * it under the terms of the GNU General Public License, version 2. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This driver is distributed in the hope that it will be useful, |
|---|
| 9 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | | - * GNU General Public License for more details. |
|---|
| 12 | | - * |
|---|
| 13 | | - * You should have received a copy of the GNU General Public License |
|---|
| 14 | | - * along with this driver. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 15 | 5 | */ |
|---|
| 16 | 6 | |
|---|
| 17 | 7 | #include <linux/init.h> |
|---|
| .. | .. |
|---|
| 106 | 96 | u8 rate_feedback[MAX_QUEUE_LENGTH]; |
|---|
| 107 | 97 | |
|---|
| 108 | 98 | struct list_head ready_playback_urbs; |
|---|
| 109 | | - struct tasklet_struct playback_tasklet; |
|---|
| 99 | + struct work_struct playback_work; |
|---|
| 110 | 100 | wait_queue_head_t alsa_capture_wait; |
|---|
| 111 | 101 | wait_queue_head_t rate_feedback_wait; |
|---|
| 112 | 102 | wait_queue_head_t alsa_playback_wait; |
|---|
| .. | .. |
|---|
| 198 | 188 | spin_lock_irqsave(&ua->lock, flags); |
|---|
| 199 | 189 | list_add_tail(&urb->ready_list, &ua->ready_playback_urbs); |
|---|
| 200 | 190 | if (ua->rate_feedback_count > 0) |
|---|
| 201 | | - tasklet_schedule(&ua->playback_tasklet); |
|---|
| 191 | + queue_work(system_highpri_wq, &ua->playback_work); |
|---|
| 202 | 192 | ua->playback.substream->runtime->delay -= |
|---|
| 203 | 193 | urb->urb.iso_frame_desc[0].length / |
|---|
| 204 | 194 | ua->playback.frame_bytes; |
|---|
| .. | .. |
|---|
| 257 | 247 | *value -= ua->playback.queue_length; |
|---|
| 258 | 248 | } |
|---|
| 259 | 249 | |
|---|
| 260 | | -static void playback_tasklet(unsigned long data) |
|---|
| 250 | +static void playback_work(struct work_struct *work) |
|---|
| 261 | 251 | { |
|---|
| 262 | | - struct ua101 *ua = (void *)data; |
|---|
| 252 | + struct ua101 *ua = container_of(work, struct ua101, playback_work); |
|---|
| 263 | 253 | unsigned long flags; |
|---|
| 264 | 254 | unsigned int frames; |
|---|
| 265 | 255 | struct ua101_urb *urb; |
|---|
| .. | .. |
|---|
| 411 | 401 | } |
|---|
| 412 | 402 | if (test_bit(USB_PLAYBACK_RUNNING, &ua->states) && |
|---|
| 413 | 403 | !list_empty(&ua->ready_playback_urbs)) |
|---|
| 414 | | - tasklet_schedule(&ua->playback_tasklet); |
|---|
| 404 | + queue_work(system_highpri_wq, &ua->playback_work); |
|---|
| 415 | 405 | } |
|---|
| 416 | 406 | |
|---|
| 417 | 407 | spin_unlock_irqrestore(&ua->lock, flags); |
|---|
| .. | .. |
|---|
| 542 | 532 | |
|---|
| 543 | 533 | kill_stream_urbs(&ua->playback); |
|---|
| 544 | 534 | |
|---|
| 545 | | - tasklet_kill(&ua->playback_tasklet); |
|---|
| 535 | + cancel_work_sync(&ua->playback_work); |
|---|
| 546 | 536 | |
|---|
| 547 | 537 | disable_iso_interface(ua, INTF_PLAYBACK); |
|---|
| 548 | 538 | } |
|---|
| .. | .. |
|---|
| 560 | 550 | return 0; |
|---|
| 561 | 551 | |
|---|
| 562 | 552 | kill_stream_urbs(&ua->playback); |
|---|
| 563 | | - tasklet_kill(&ua->playback_tasklet); |
|---|
| 553 | + cancel_work_sync(&ua->playback_work); |
|---|
| 564 | 554 | |
|---|
| 565 | 555 | err = enable_iso_interface(ua, INTF_PLAYBACK); |
|---|
| 566 | 556 | if (err < 0) |
|---|
| .. | .. |
|---|
| 740 | 730 | mutex_lock(&ua->mutex); |
|---|
| 741 | 731 | err = start_usb_capture(ua); |
|---|
| 742 | 732 | mutex_unlock(&ua->mutex); |
|---|
| 743 | | - if (err < 0) |
|---|
| 744 | | - return err; |
|---|
| 745 | | - |
|---|
| 746 | | - return snd_pcm_lib_alloc_vmalloc_buffer(substream, |
|---|
| 747 | | - params_buffer_bytes(hw_params)); |
|---|
| 733 | + return err; |
|---|
| 748 | 734 | } |
|---|
| 749 | 735 | |
|---|
| 750 | 736 | static int playback_pcm_hw_params(struct snd_pcm_substream *substream, |
|---|
| .. | .. |
|---|
| 758 | 744 | if (err >= 0) |
|---|
| 759 | 745 | err = start_usb_playback(ua); |
|---|
| 760 | 746 | mutex_unlock(&ua->mutex); |
|---|
| 761 | | - if (err < 0) |
|---|
| 762 | | - return err; |
|---|
| 763 | | - |
|---|
| 764 | | - return snd_pcm_lib_alloc_vmalloc_buffer(substream, |
|---|
| 765 | | - params_buffer_bytes(hw_params)); |
|---|
| 766 | | -} |
|---|
| 767 | | - |
|---|
| 768 | | -static int ua101_pcm_hw_free(struct snd_pcm_substream *substream) |
|---|
| 769 | | -{ |
|---|
| 770 | | - return snd_pcm_lib_free_vmalloc_buffer(substream); |
|---|
| 747 | + return err; |
|---|
| 771 | 748 | } |
|---|
| 772 | 749 | |
|---|
| 773 | 750 | static int capture_pcm_prepare(struct snd_pcm_substream *substream) |
|---|
| .. | .. |
|---|
| 893 | 870 | static const struct snd_pcm_ops capture_pcm_ops = { |
|---|
| 894 | 871 | .open = capture_pcm_open, |
|---|
| 895 | 872 | .close = capture_pcm_close, |
|---|
| 896 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 897 | 873 | .hw_params = capture_pcm_hw_params, |
|---|
| 898 | | - .hw_free = ua101_pcm_hw_free, |
|---|
| 899 | 874 | .prepare = capture_pcm_prepare, |
|---|
| 900 | 875 | .trigger = capture_pcm_trigger, |
|---|
| 901 | 876 | .pointer = capture_pcm_pointer, |
|---|
| 902 | | - .page = snd_pcm_lib_get_vmalloc_page, |
|---|
| 903 | 877 | }; |
|---|
| 904 | 878 | |
|---|
| 905 | 879 | static const struct snd_pcm_ops playback_pcm_ops = { |
|---|
| 906 | 880 | .open = playback_pcm_open, |
|---|
| 907 | 881 | .close = playback_pcm_close, |
|---|
| 908 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 909 | 882 | .hw_params = playback_pcm_hw_params, |
|---|
| 910 | | - .hw_free = ua101_pcm_hw_free, |
|---|
| 911 | 883 | .prepare = playback_pcm_prepare, |
|---|
| 912 | 884 | .trigger = playback_pcm_trigger, |
|---|
| 913 | 885 | .pointer = playback_pcm_pointer, |
|---|
| 914 | | - .page = snd_pcm_lib_get_vmalloc_page, |
|---|
| 915 | 886 | }; |
|---|
| 916 | 887 | |
|---|
| 917 | 888 | static const struct uac_format_type_i_discrete_descriptor * |
|---|
| .. | .. |
|---|
| 1247 | 1218 | spin_lock_init(&ua->lock); |
|---|
| 1248 | 1219 | mutex_init(&ua->mutex); |
|---|
| 1249 | 1220 | INIT_LIST_HEAD(&ua->ready_playback_urbs); |
|---|
| 1250 | | - tasklet_init(&ua->playback_tasklet, |
|---|
| 1251 | | - playback_tasklet, (unsigned long)ua); |
|---|
| 1221 | + INIT_WORK(&ua->playback_work, playback_work); |
|---|
| 1252 | 1222 | init_waitqueue_head(&ua->alsa_capture_wait); |
|---|
| 1253 | 1223 | init_waitqueue_head(&ua->rate_feedback_wait); |
|---|
| 1254 | 1224 | init_waitqueue_head(&ua->alsa_playback_wait); |
|---|
| .. | .. |
|---|
| 1306 | 1276 | strcpy(ua->pcm->name, name); |
|---|
| 1307 | 1277 | snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_pcm_ops); |
|---|
| 1308 | 1278 | snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_pcm_ops); |
|---|
| 1279 | + snd_pcm_set_managed_buffer_all(ua->pcm, SNDRV_DMA_TYPE_VMALLOC, |
|---|
| 1280 | + NULL, 0, 0); |
|---|
| 1309 | 1281 | |
|---|
| 1310 | 1282 | err = snd_usbmidi_create(card, ua->intf[INTF_MIDI], |
|---|
| 1311 | 1283 | &ua->midi_list, &midi_quirk); |
|---|