diff options
author | Takashi Iwai <tiwai@suse.de> | 2019-05-08 15:24:00 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2019-05-28 08:56:59 +0200 |
commit | 516d3d1bedd34b2008f3530e4957ef97d449d5f7 (patch) | |
tree | d949c30af0c8b233f5dc3915fb68f80e93e97b64 | |
parent | 0b074ab7fc0d575247b9cc9f93bb7e007ca38840 (diff) | |
download | lwn-516d3d1bedd34b2008f3530e4957ef97d449d5f7.tar.gz lwn-516d3d1bedd34b2008f3530e4957ef97d449d5f7.zip |
ALSA: line6: pod: Rewrite complex timer & work combo with a delayed work
The POD driver had a complex staged startup procedure using both timer
and work. This patch simplifies it via a single delayed work with the
reduced stages.
Now basically only two intermediate stages:
- POD_STARTUP_VERSIONREQ:
requesting the version information and the process_message callback
triggers the next stage,
- POD_STARTUP_SETUP:
registering the actual card object.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/usb/line6/pod.c | 96 |
1 files changed, 27 insertions, 69 deletions
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index ce45b6dab651..995e6ccc8122 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -39,11 +39,9 @@ Stages of POD startup procedure */ enum { - POD_STARTUP_INIT = 1, POD_STARTUP_VERSIONREQ, - POD_STARTUP_WORKQUEUE, POD_STARTUP_SETUP, - POD_STARTUP_LAST = POD_STARTUP_SETUP - 1 + POD_STARTUP_DONE, }; enum { @@ -63,12 +61,6 @@ struct usb_line6_pod { /* Instrument monitor level */ int monitor_level; - /* Timer for device initialization */ - struct timer_list startup_timer; - - /* Work handler for device initialization */ - struct work_struct startup_work; - /* Current progress in startup procedure */ int startup_progress; @@ -173,10 +165,6 @@ static const char pod_version_header[] = { 0xf2, 0x7e, 0x7f, 0x06, 0x02 }; -/* forward declarations: */ -static void pod_startup2(struct timer_list *t); -static void pod_startup3(struct usb_line6_pod *pod); - static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, int size) { @@ -196,7 +184,10 @@ static void line6_pod_process_message(struct usb_line6 *line6) pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15]; pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int) buf[10]; - pod_startup3(pod); + if (pod->startup_progress == POD_STARTUP_VERSIONREQ) { + pod->startup_progress = POD_STARTUP_SETUP; + schedule_delayed_work(&line6->startup_work, 0); + } return; } @@ -281,47 +272,27 @@ static ssize_t device_id_show(struct device *dev, context). After the last one has finished, the device is ready to use. */ -static void pod_startup1(struct usb_line6_pod *pod) -{ - CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT); - - /* delay startup procedure: */ - line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2); -} - -static void pod_startup2(struct timer_list *t) +static void pod_startup(struct usb_line6 *line6) { - struct usb_line6_pod *pod = from_timer(pod, t, startup_timer); - struct usb_line6 *line6 = &pod->line6; - - CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ); - - /* request firmware version: */ - line6_version_request_async(line6); -} - -static void pod_startup3(struct usb_line6_pod *pod) -{ - CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE); - - /* schedule work for global work queue: */ - schedule_work(&pod->startup_work); -} - -static void pod_startup4(struct work_struct *work) -{ - struct usb_line6_pod *pod = - container_of(work, struct usb_line6_pod, startup_work); - struct usb_line6 *line6 = &pod->line6; - - CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP); - - /* serial number: */ - line6_read_serial_number(&pod->line6, &pod->serial_number); + struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; - /* ALSA audio interface: */ - if (snd_card_register(line6->card)) - dev_err(line6->ifcdev, "Failed to register POD card.\n"); + switch (pod->startup_progress) { + case POD_STARTUP_VERSIONREQ: + /* request firmware version: */ + line6_version_request_async(line6); + break; + case POD_STARTUP_SETUP: + /* serial number: */ + line6_read_serial_number(&pod->line6, &pod->serial_number); + + /* ALSA audio interface: */ + if (snd_card_register(line6->card)) + dev_err(line6->ifcdev, "Failed to register POD card.\n"); + pod->startup_progress = POD_STARTUP_DONE; + break; + default: + break; + } } /* POD special files: */ @@ -391,17 +362,6 @@ static const struct snd_kcontrol_new pod_control_monitor = { }; /* - POD device disconnected. -*/ -static void line6_pod_disconnect(struct usb_line6 *line6) -{ - struct usb_line6_pod *pod = (struct usb_line6_pod *)line6; - - del_timer_sync(&pod->startup_timer); - cancel_work_sync(&pod->startup_work); -} - -/* Try to init POD device. */ static int pod_init(struct usb_line6 *line6, @@ -411,10 +371,7 @@ static int pod_init(struct usb_line6 *line6, struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; line6->process_message = line6_pod_process_message; - line6->disconnect = line6_pod_disconnect; - - timer_setup(&pod->startup_timer, NULL, 0); - INIT_WORK(&pod->startup_work, pod_startup4); + line6->startup = pod_startup; /* create sysfs entries: */ err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group); @@ -447,7 +404,8 @@ static int pod_init(struct usb_line6 *line6, pod->monitor_level = POD_SYSTEM_INVALID; /* initiate startup procedure: */ - pod_startup1(pod); + schedule_delayed_work(&line6->startup_work, + msecs_to_jiffies(POD_STARTUP_DELAY)); } return 0; |