Commit 516d3d1b authored by Takashi Iwai's avatar Takashi Iwai

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: default avatarTakashi Iwai <tiwai@suse.de>
parent 0b074ab7
...@@ -39,11 +39,9 @@ ...@@ -39,11 +39,9 @@
Stages of POD startup procedure Stages of POD startup procedure
*/ */
enum { enum {
POD_STARTUP_INIT = 1,
POD_STARTUP_VERSIONREQ, POD_STARTUP_VERSIONREQ,
POD_STARTUP_WORKQUEUE,
POD_STARTUP_SETUP, POD_STARTUP_SETUP,
POD_STARTUP_LAST = POD_STARTUP_SETUP - 1 POD_STARTUP_DONE,
}; };
enum { enum {
...@@ -63,12 +61,6 @@ struct usb_line6_pod { ...@@ -63,12 +61,6 @@ struct usb_line6_pod {
/* Instrument monitor level */ /* Instrument monitor level */
int 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 */ /* Current progress in startup procedure */
int startup_progress; int startup_progress;
...@@ -173,10 +165,6 @@ static const char pod_version_header[] = { ...@@ -173,10 +165,6 @@ static const char pod_version_header[] = {
0xf2, 0x7e, 0x7f, 0x06, 0x02 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, static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
int size) int size)
{ {
...@@ -196,7 +184,10 @@ static void line6_pod_process_message(struct usb_line6 *line6) ...@@ -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->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
(int) buf[10]; (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; return;
} }
...@@ -281,47 +272,27 @@ static ssize_t device_id_show(struct device *dev, ...@@ -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. context). After the last one has finished, the device is ready to use.
*/ */
static void pod_startup1(struct usb_line6_pod *pod) static void pod_startup(struct usb_line6 *line6)
{
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)
{ {
struct usb_line6_pod *pod = from_timer(pod, t, startup_timer); struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
struct usb_line6 *line6 = &pod->line6;
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
switch (pod->startup_progress) {
case POD_STARTUP_VERSIONREQ:
/* request firmware version: */ /* request firmware version: */
line6_version_request_async(line6); line6_version_request_async(line6);
} break;
case POD_STARTUP_SETUP:
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: */ /* serial number: */
line6_read_serial_number(&pod->line6, &pod->serial_number); line6_read_serial_number(&pod->line6, &pod->serial_number);
/* ALSA audio interface: */ /* ALSA audio interface: */
if (snd_card_register(line6->card)) if (snd_card_register(line6->card))
dev_err(line6->ifcdev, "Failed to register POD card.\n"); dev_err(line6->ifcdev, "Failed to register POD card.\n");
pod->startup_progress = POD_STARTUP_DONE;
break;
default:
break;
}
} }
/* POD special files: */ /* POD special files: */
...@@ -390,17 +361,6 @@ static const struct snd_kcontrol_new pod_control_monitor = { ...@@ -390,17 +361,6 @@ static const struct snd_kcontrol_new pod_control_monitor = {
.put = snd_pod_control_monitor_put .put = snd_pod_control_monitor_put
}; };
/*
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. Try to init POD device.
*/ */
...@@ -411,10 +371,7 @@ 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; struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
line6->process_message = line6_pod_process_message; line6->process_message = line6_pod_process_message;
line6->disconnect = line6_pod_disconnect; line6->startup = pod_startup;
timer_setup(&pod->startup_timer, NULL, 0);
INIT_WORK(&pod->startup_work, pod_startup4);
/* create sysfs entries: */ /* create sysfs entries: */
err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group); err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group);
...@@ -447,7 +404,8 @@ static int pod_init(struct usb_line6 *line6, ...@@ -447,7 +404,8 @@ static int pod_init(struct usb_line6 *line6,
pod->monitor_level = POD_SYSTEM_INVALID; pod->monitor_level = POD_SYSTEM_INVALID;
/* initiate startup procedure: */ /* initiate startup procedure: */
pod_startup1(pod); schedule_delayed_work(&line6->startup_work,
msecs_to_jiffies(POD_STARTUP_DELAY));
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment