.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * ALSA driver for RME Hammerfall DSP audio interface(s) |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2002 Paul Davis |
---|
5 | 6 | * Marcus Andersson |
---|
6 | 7 | * Thomas Charbonnel |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License as published by |
---|
10 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
11 | | - * (at your option) any later version. |
---|
12 | | - * |
---|
13 | | - * This program is distributed in the hope that it will be useful, |
---|
14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
16 | | - * GNU General Public License for more details. |
---|
17 | | - * |
---|
18 | | - * You should have received a copy of the GNU General Public License |
---|
19 | | - * along with this program; if not, write to the Free Software |
---|
20 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
21 | | - * |
---|
22 | 8 | */ |
---|
23 | 9 | |
---|
24 | 10 | #include <linux/init.h> |
---|
.. | .. |
---|
450 | 436 | struct snd_rawmidi *rmidi; |
---|
451 | 437 | struct snd_rawmidi_substream *input; |
---|
452 | 438 | struct snd_rawmidi_substream *output; |
---|
453 | | - char istimer; /* timer in use */ |
---|
| 439 | + signed char istimer; /* timer in use */ |
---|
454 | 440 | struct timer_list timer; |
---|
455 | 441 | spinlock_t lock; |
---|
456 | 442 | int pending; |
---|
.. | .. |
---|
461 | 447 | struct snd_pcm_substream *capture_substream; |
---|
462 | 448 | struct snd_pcm_substream *playback_substream; |
---|
463 | 449 | struct hdsp_midi midi[2]; |
---|
464 | | - struct tasklet_struct midi_tasklet; |
---|
465 | | - int use_midi_tasklet; |
---|
| 450 | + struct work_struct midi_work; |
---|
| 451 | + int use_midi_work; |
---|
466 | 452 | int precise_ptr; |
---|
467 | 453 | u32 control_register; /* cached value */ |
---|
468 | 454 | u32 control2_register; /* cached value */ |
---|
.. | .. |
---|
493 | 479 | pid_t playback_pid; |
---|
494 | 480 | int running; |
---|
495 | 481 | int system_sample_rate; |
---|
496 | | - char *channel_map; |
---|
| 482 | + const signed char *channel_map; |
---|
497 | 483 | int dev; |
---|
498 | 484 | int irq; |
---|
499 | 485 | unsigned long port; |
---|
.. | .. |
---|
515 | 501 | where the data for that channel can be read/written from/to. |
---|
516 | 502 | */ |
---|
517 | 503 | |
---|
518 | | -static char channel_map_df_ss[HDSP_MAX_CHANNELS] = { |
---|
| 504 | +static const signed char channel_map_df_ss[HDSP_MAX_CHANNELS] = { |
---|
519 | 505 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, |
---|
520 | 506 | 18, 19, 20, 21, 22, 23, 24, 25 |
---|
521 | 507 | }; |
---|
522 | 508 | |
---|
523 | | -static char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */ |
---|
| 509 | +static const char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */ |
---|
524 | 510 | /* Analog */ |
---|
525 | 511 | 0, 1, 2, 3, 4, 5, 6, 7, |
---|
526 | 512 | /* ADAT 2 */ |
---|
.. | .. |
---|
530 | 516 | -1, -1, -1, -1, -1, -1, -1, -1 |
---|
531 | 517 | }; |
---|
532 | 518 | |
---|
533 | | -static char channel_map_ds[HDSP_MAX_CHANNELS] = { |
---|
| 519 | +static const signed char channel_map_ds[HDSP_MAX_CHANNELS] = { |
---|
534 | 520 | /* ADAT channels are remapped */ |
---|
535 | 521 | 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, |
---|
536 | 522 | /* channels 12 and 13 are S/PDIF */ |
---|
.. | .. |
---|
539 | 525 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 |
---|
540 | 526 | }; |
---|
541 | 527 | |
---|
542 | | -static char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = { |
---|
| 528 | +static const signed char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = { |
---|
543 | 529 | /* ADAT channels */ |
---|
544 | 530 | 0, 1, 2, 3, 4, 5, 6, 7, |
---|
545 | 531 | /* SPDIF */ |
---|
.. | .. |
---|
553 | 539 | -1, -1 |
---|
554 | 540 | }; |
---|
555 | 541 | |
---|
556 | | -static char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = { |
---|
| 542 | +static const signed char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = { |
---|
557 | 543 | /* ADAT */ |
---|
558 | 544 | 1, 3, 5, 7, |
---|
559 | 545 | /* SPDIF */ |
---|
.. | .. |
---|
567 | 553 | -1, -1, -1, -1, -1, -1 |
---|
568 | 554 | }; |
---|
569 | 555 | |
---|
570 | | -static char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = { |
---|
| 556 | +static const signed char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = { |
---|
571 | 557 | /* ADAT is disabled in this mode */ |
---|
572 | 558 | /* SPDIF */ |
---|
573 | 559 | 8, 9, |
---|
.. | .. |
---|
583 | 569 | |
---|
584 | 570 | static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size) |
---|
585 | 571 | { |
---|
586 | | - dmab->dev.type = SNDRV_DMA_TYPE_DEV; |
---|
587 | | - dmab->dev.dev = snd_dma_pci_data(pci); |
---|
588 | | - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), |
---|
589 | | - size, dmab) < 0) |
---|
590 | | - return -ENOMEM; |
---|
591 | | - return 0; |
---|
| 572 | + return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, size, dmab); |
---|
592 | 573 | } |
---|
593 | 574 | |
---|
594 | 575 | static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci) |
---|
.. | .. |
---|
1404 | 1385 | } |
---|
1405 | 1386 | } else { |
---|
1406 | 1387 | hdsp->control_register &= ~ie; |
---|
1407 | | - tasklet_kill(&hdsp->midi_tasklet); |
---|
1408 | 1388 | } |
---|
1409 | 1389 | |
---|
1410 | 1390 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); |
---|
.. | .. |
---|
2561 | 2541 | return change; |
---|
2562 | 2542 | } |
---|
2563 | 2543 | |
---|
2564 | | -#define HDSP_USE_MIDI_TASKLET(xname, xindex) \ |
---|
| 2544 | +#define HDSP_USE_MIDI_WORK(xname, xindex) \ |
---|
2565 | 2545 | { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ |
---|
2566 | 2546 | .name = xname, \ |
---|
2567 | 2547 | .index = xindex, \ |
---|
2568 | | - .info = snd_hdsp_info_use_midi_tasklet, \ |
---|
2569 | | - .get = snd_hdsp_get_use_midi_tasklet, \ |
---|
2570 | | - .put = snd_hdsp_put_use_midi_tasklet \ |
---|
| 2548 | + .info = snd_hdsp_info_use_midi_work, \ |
---|
| 2549 | + .get = snd_hdsp_get_use_midi_work, \ |
---|
| 2550 | + .put = snd_hdsp_put_use_midi_work \ |
---|
2571 | 2551 | } |
---|
2572 | 2552 | |
---|
2573 | | -static int hdsp_set_use_midi_tasklet(struct hdsp *hdsp, int use_tasklet) |
---|
| 2553 | +static int hdsp_set_use_midi_work(struct hdsp *hdsp, int use_work) |
---|
2574 | 2554 | { |
---|
2575 | | - if (use_tasklet) |
---|
2576 | | - hdsp->use_midi_tasklet = 1; |
---|
| 2555 | + if (use_work) |
---|
| 2556 | + hdsp->use_midi_work = 1; |
---|
2577 | 2557 | else |
---|
2578 | | - hdsp->use_midi_tasklet = 0; |
---|
| 2558 | + hdsp->use_midi_work = 0; |
---|
2579 | 2559 | return 0; |
---|
2580 | 2560 | } |
---|
2581 | 2561 | |
---|
2582 | | -#define snd_hdsp_info_use_midi_tasklet snd_ctl_boolean_mono_info |
---|
| 2562 | +#define snd_hdsp_info_use_midi_work snd_ctl_boolean_mono_info |
---|
2583 | 2563 | |
---|
2584 | | -static int snd_hdsp_get_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
---|
| 2564 | +static int snd_hdsp_get_use_midi_work(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
---|
2585 | 2565 | { |
---|
2586 | 2566 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
---|
2587 | 2567 | |
---|
2588 | 2568 | spin_lock_irq(&hdsp->lock); |
---|
2589 | | - ucontrol->value.integer.value[0] = hdsp->use_midi_tasklet; |
---|
| 2569 | + ucontrol->value.integer.value[0] = hdsp->use_midi_work; |
---|
2590 | 2570 | spin_unlock_irq(&hdsp->lock); |
---|
2591 | 2571 | return 0; |
---|
2592 | 2572 | } |
---|
2593 | 2573 | |
---|
2594 | | -static int snd_hdsp_put_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
---|
| 2574 | +static int snd_hdsp_put_use_midi_work(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
---|
2595 | 2575 | { |
---|
2596 | 2576 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
---|
2597 | 2577 | int change; |
---|
.. | .. |
---|
2601 | 2581 | return -EBUSY; |
---|
2602 | 2582 | val = ucontrol->value.integer.value[0] & 1; |
---|
2603 | 2583 | spin_lock_irq(&hdsp->lock); |
---|
2604 | | - change = (int)val != hdsp->use_midi_tasklet; |
---|
2605 | | - hdsp_set_use_midi_tasklet(hdsp, val); |
---|
| 2584 | + change = (int)val != hdsp->use_midi_work; |
---|
| 2585 | + hdsp_set_use_midi_work(hdsp, val); |
---|
2606 | 2586 | spin_unlock_irq(&hdsp->lock); |
---|
2607 | 2587 | return change; |
---|
2608 | 2588 | } |
---|
.. | .. |
---|
2898 | 2878 | return change; |
---|
2899 | 2879 | } |
---|
2900 | 2880 | |
---|
2901 | | -static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { |
---|
| 2881 | +static const struct snd_kcontrol_new snd_hdsp_9632_controls[] = { |
---|
2902 | 2882 | HDSP_DA_GAIN("DA Gain", 0), |
---|
2903 | 2883 | HDSP_AD_GAIN("AD Gain", 0), |
---|
2904 | 2884 | HDSP_PHONE_GAIN("Phones Gain", 0), |
---|
.. | .. |
---|
2906 | 2886 | HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) |
---|
2907 | 2887 | }; |
---|
2908 | 2888 | |
---|
2909 | | -static struct snd_kcontrol_new snd_hdsp_controls[] = { |
---|
| 2889 | +static const struct snd_kcontrol_new snd_hdsp_controls[] = { |
---|
2910 | 2890 | { |
---|
2911 | 2891 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
---|
2912 | 2892 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
---|
.. | .. |
---|
2969 | 2949 | HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0), |
---|
2970 | 2950 | HDSP_TOGGLE_SETTING("Line Out", HDSP_LineOut), |
---|
2971 | 2951 | HDSP_PRECISE_POINTER("Precise Pointer", 0), |
---|
2972 | | -HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), |
---|
| 2952 | +HDSP_USE_MIDI_WORK("Use Midi Tasklet", 0), |
---|
2973 | 2953 | }; |
---|
2974 | 2954 | |
---|
2975 | 2955 | |
---|
.. | .. |
---|
3235 | 3215 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
---|
3236 | 3216 | } |
---|
3237 | 3217 | |
---|
3238 | | -static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { |
---|
| 3218 | +static const struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { |
---|
3239 | 3219 | { |
---|
3240 | 3220 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
---|
3241 | 3221 | .name = "RPM Bypass", |
---|
.. | .. |
---|
3268 | 3248 | HDSP_MIXER("Mixer", 0) |
---|
3269 | 3249 | }; |
---|
3270 | 3250 | |
---|
3271 | | -static struct snd_kcontrol_new snd_hdsp_96xx_aeb = |
---|
| 3251 | +static const struct snd_kcontrol_new snd_hdsp_96xx_aeb = |
---|
3272 | 3252 | HDSP_TOGGLE_SETTING("Analog Extension Board", |
---|
3273 | 3253 | HDSP_AnalogExtensionBoard); |
---|
3274 | 3254 | static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; |
---|
.. | .. |
---|
3372 | 3352 | return; |
---|
3373 | 3353 | } |
---|
3374 | 3354 | } else { |
---|
3375 | | - int err = -EINVAL; |
---|
| 3355 | + int err; |
---|
| 3356 | + |
---|
3376 | 3357 | err = hdsp_request_fw_loader(hdsp); |
---|
3377 | 3358 | if (err < 0) { |
---|
3378 | 3359 | snd_iprintf(buffer, |
---|
.. | .. |
---|
3388 | 3369 | snd_iprintf(buffer, "MIDI1 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn0)); |
---|
3389 | 3370 | snd_iprintf(buffer, "MIDI2 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut1)); |
---|
3390 | 3371 | snd_iprintf(buffer, "MIDI2 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn1)); |
---|
3391 | | - snd_iprintf(buffer, "Use Midi Tasklet: %s\n", hdsp->use_midi_tasklet ? "on" : "off"); |
---|
| 3372 | + snd_iprintf(buffer, "Use Midi Tasklet: %s\n", hdsp->use_midi_work ? "on" : "off"); |
---|
3392 | 3373 | |
---|
3393 | 3374 | snd_iprintf(buffer, "\n"); |
---|
3394 | 3375 | |
---|
.. | .. |
---|
3708 | 3689 | |
---|
3709 | 3690 | static void snd_hdsp_proc_init(struct hdsp *hdsp) |
---|
3710 | 3691 | { |
---|
3711 | | - struct snd_info_entry *entry; |
---|
3712 | | - |
---|
3713 | | - if (! snd_card_proc_new(hdsp->card, "hdsp", &entry)) |
---|
3714 | | - snd_info_set_text_ops(entry, hdsp, snd_hdsp_proc_read); |
---|
| 3692 | + snd_card_ro_proc_new(hdsp->card, "hdsp", hdsp, snd_hdsp_proc_read); |
---|
3715 | 3693 | } |
---|
3716 | 3694 | |
---|
3717 | 3695 | static void snd_hdsp_free_buffers(struct hdsp *hdsp) |
---|
.. | .. |
---|
3812 | 3790 | return 0; |
---|
3813 | 3791 | } |
---|
3814 | 3792 | |
---|
3815 | | -static void hdsp_midi_tasklet(unsigned long arg) |
---|
| 3793 | +static void hdsp_midi_work(struct work_struct *work) |
---|
3816 | 3794 | { |
---|
3817 | | - struct hdsp *hdsp = (struct hdsp *)arg; |
---|
| 3795 | + struct hdsp *hdsp = container_of(work, struct hdsp, midi_work); |
---|
3818 | 3796 | |
---|
3819 | 3797 | if (hdsp->midi[0].pending) |
---|
3820 | 3798 | snd_hdsp_midi_input_read (&hdsp->midi[0]); |
---|
.. | .. |
---|
3859 | 3837 | } |
---|
3860 | 3838 | |
---|
3861 | 3839 | if (midi0 && midi0status) { |
---|
3862 | | - if (hdsp->use_midi_tasklet) { |
---|
| 3840 | + if (hdsp->use_midi_work) { |
---|
3863 | 3841 | /* we disable interrupts for this input until processing is done */ |
---|
3864 | 3842 | hdsp->control_register &= ~HDSP_Midi0InterruptEnable; |
---|
3865 | 3843 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); |
---|
.. | .. |
---|
3870 | 3848 | } |
---|
3871 | 3849 | } |
---|
3872 | 3850 | if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) { |
---|
3873 | | - if (hdsp->use_midi_tasklet) { |
---|
| 3851 | + if (hdsp->use_midi_work) { |
---|
3874 | 3852 | /* we disable interrupts for this input until processing is done */ |
---|
3875 | 3853 | hdsp->control_register &= ~HDSP_Midi1InterruptEnable; |
---|
3876 | 3854 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); |
---|
.. | .. |
---|
3880 | 3858 | snd_hdsp_midi_input_read (&hdsp->midi[1]); |
---|
3881 | 3859 | } |
---|
3882 | 3860 | } |
---|
3883 | | - if (hdsp->use_midi_tasklet && schedule) |
---|
3884 | | - tasklet_schedule(&hdsp->midi_tasklet); |
---|
| 3861 | + if (hdsp->use_midi_work && schedule) |
---|
| 3862 | + queue_work(system_highpri_wq, &hdsp->midi_work); |
---|
3885 | 3863 | return IRQ_HANDLED; |
---|
3886 | 3864 | } |
---|
3887 | 3865 | |
---|
.. | .. |
---|
3891 | 3869 | return hdsp_hw_pointer(hdsp); |
---|
3892 | 3870 | } |
---|
3893 | 3871 | |
---|
3894 | | -static char *hdsp_channel_buffer_location(struct hdsp *hdsp, |
---|
| 3872 | +static signed char *hdsp_channel_buffer_location(struct hdsp *hdsp, |
---|
3895 | 3873 | int stream, |
---|
3896 | 3874 | int channel) |
---|
3897 | 3875 | |
---|
.. | .. |
---|
3915 | 3893 | void __user *src, unsigned long count) |
---|
3916 | 3894 | { |
---|
3917 | 3895 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); |
---|
3918 | | - char *channel_buf; |
---|
| 3896 | + signed char *channel_buf; |
---|
3919 | 3897 | |
---|
3920 | 3898 | if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES)) |
---|
3921 | 3899 | return -EINVAL; |
---|
.. | .. |
---|
3933 | 3911 | void *src, unsigned long count) |
---|
3934 | 3912 | { |
---|
3935 | 3913 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); |
---|
3936 | | - char *channel_buf; |
---|
| 3914 | + signed char *channel_buf; |
---|
3937 | 3915 | |
---|
3938 | 3916 | channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel); |
---|
3939 | 3917 | if (snd_BUG_ON(!channel_buf)) |
---|
.. | .. |
---|
3947 | 3925 | void __user *dst, unsigned long count) |
---|
3948 | 3926 | { |
---|
3949 | 3927 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); |
---|
3950 | | - char *channel_buf; |
---|
| 3928 | + signed char *channel_buf; |
---|
3951 | 3929 | |
---|
3952 | 3930 | if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES)) |
---|
3953 | 3931 | return -EINVAL; |
---|
.. | .. |
---|
3965 | 3943 | void *dst, unsigned long count) |
---|
3966 | 3944 | { |
---|
3967 | 3945 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); |
---|
3968 | | - char *channel_buf; |
---|
| 3946 | + signed char *channel_buf; |
---|
3969 | 3947 | |
---|
3970 | 3948 | channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel); |
---|
3971 | 3949 | if (snd_BUG_ON(!channel_buf)) |
---|
.. | .. |
---|
3979 | 3957 | unsigned long count) |
---|
3980 | 3958 | { |
---|
3981 | 3959 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); |
---|
3982 | | - char *channel_buf; |
---|
| 3960 | + signed char *channel_buf; |
---|
3983 | 3961 | |
---|
3984 | 3962 | channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); |
---|
3985 | 3963 | if (snd_BUG_ON(!channel_buf)) |
---|
.. | .. |
---|
4824 | 4802 | break; |
---|
4825 | 4803 | } |
---|
4826 | 4804 | case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: { |
---|
4827 | | - struct hdsp_firmware __user *firmware; |
---|
| 4805 | + struct hdsp_firmware firmware; |
---|
4828 | 4806 | u32 __user *firmware_data; |
---|
4829 | 4807 | int err; |
---|
4830 | 4808 | |
---|
.. | .. |
---|
4837 | 4815 | |
---|
4838 | 4816 | dev_info(hdsp->card->dev, |
---|
4839 | 4817 | "initializing firmware upload\n"); |
---|
4840 | | - firmware = (struct hdsp_firmware __user *)argp; |
---|
4841 | | - |
---|
4842 | | - if (get_user(firmware_data, &firmware->firmware_data)) |
---|
| 4818 | + if (copy_from_user(&firmware, argp, sizeof(firmware))) |
---|
4843 | 4819 | return -EFAULT; |
---|
| 4820 | + firmware_data = (u32 __user *)firmware.firmware_data; |
---|
4844 | 4821 | |
---|
4845 | 4822 | if (hdsp_check_for_iobox (hdsp)) |
---|
4846 | 4823 | return -EIO; |
---|
.. | .. |
---|
5204 | 5181 | |
---|
5205 | 5182 | spin_lock_init(&hdsp->lock); |
---|
5206 | 5183 | |
---|
5207 | | - tasklet_init(&hdsp->midi_tasklet, hdsp_midi_tasklet, (unsigned long)hdsp); |
---|
| 5184 | + INIT_WORK(&hdsp->midi_work, hdsp_midi_work); |
---|
5208 | 5185 | |
---|
5209 | 5186 | pci_read_config_word(hdsp->pci, PCI_CLASS_REVISION, &hdsp->firmware_rev); |
---|
5210 | 5187 | hdsp->firmware_rev &= 0xff; |
---|
.. | .. |
---|
5242 | 5219 | if ((err = pci_request_regions(pci, "hdsp")) < 0) |
---|
5243 | 5220 | return err; |
---|
5244 | 5221 | hdsp->port = pci_resource_start(pci, 0); |
---|
5245 | | - if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) { |
---|
| 5222 | + if ((hdsp->iobase = ioremap(hdsp->port, HDSP_IO_EXTENT)) == NULL) { |
---|
5246 | 5223 | dev_err(hdsp->card->dev, "unable to remap region 0x%lx-0x%lx\n", |
---|
5247 | 5224 | hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1); |
---|
5248 | 5225 | return -EBUSY; |
---|
.. | .. |
---|
5255 | 5232 | } |
---|
5256 | 5233 | |
---|
5257 | 5234 | hdsp->irq = pci->irq; |
---|
| 5235 | + card->sync_irq = hdsp->irq; |
---|
5258 | 5236 | hdsp->precise_ptr = 0; |
---|
5259 | | - hdsp->use_midi_tasklet = 1; |
---|
| 5237 | + hdsp->use_midi_work = 1; |
---|
5260 | 5238 | hdsp->dds_value = 0; |
---|
5261 | 5239 | |
---|
5262 | 5240 | if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) |
---|
.. | .. |
---|
5326 | 5304 | { |
---|
5327 | 5305 | if (hdsp->port) { |
---|
5328 | 5306 | /* stop the audio, and cancel all interrupts */ |
---|
5329 | | - tasklet_kill(&hdsp->midi_tasklet); |
---|
| 5307 | + cancel_work_sync(&hdsp->midi_work); |
---|
5330 | 5308 | hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable); |
---|
5331 | 5309 | hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register); |
---|
5332 | 5310 | } |
---|