unsol->queue[wp] = res;
        unsol->queue[wp + 1] = res_ex;
 
-       schedule_work(&unsol->work);
+       queue_work(bus->workq, &unsol->work);
 
        return 0;
 }
 
        if (!bus)
                return 0;
-       if (bus->unsol) {
-               flush_scheduled_work();
+       if (bus->workq)
+               flush_workqueue(bus->workq);
+       if (bus->unsol)
                kfree(bus->unsol);
-       }
        list_for_each_entry_safe(codec, n, &bus->codec_list, list) {
                snd_hda_codec_free(codec);
        }
        if (bus->ops.private_free)
                bus->ops.private_free(bus);
+       if (bus->workq)
+               destroy_workqueue(bus->workq);
        kfree(bus);
        return 0;
 }
 {
        struct hda_bus *bus;
        int err;
+       char qname[8];
        static struct snd_device_ops dev_ops = {
                .dev_register = snd_hda_bus_dev_register,
                .dev_free = snd_hda_bus_dev_free,
        mutex_init(&bus->cmd_mutex);
        INIT_LIST_HEAD(&bus->codec_list);
 
+       snprintf(qname, sizeof(qname), "hda%d", card->number);
+       bus->workq = create_workqueue(qname);
+       if (!bus->workq) {
+               snd_printk(KERN_ERR "cannot create workqueue %s\n", qname);
+               kfree(bus);
+               return -ENOMEM;
+       }
+
        err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
        if (err < 0) {
                snd_hda_bus_free(bus);
                return;
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        cancel_delayed_work(&codec->power_work);
-       flush_scheduled_work();
+       flush_workqueue(codec->bus->workq);
 #endif
        list_del(&codec->list);
        snd_array_free(&codec->mixers);
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        cancel_delayed_work(&codec->power_work);
-       flush_scheduled_work();
+       flush_workqueue(codec->bus->workq);
 #endif
        snd_hda_ctls_clear(codec);
        /* relase PCMs */
 
                                spin_unlock(&chip->reg_lock);
                                snd_pcm_period_elapsed(azx_dev->substream);
                                spin_lock(&chip->reg_lock);
-                       } else {
+                       } else if (chip->bus && chip->bus->workq) {
                                /* bogus IRQ, process it later */
                                azx_dev->irq_pending = 1;
-                               schedule_work(&chip->irq_pending_work);
+                               queue_work(chip->bus->workq,
+                                          &chip->irq_pending_work);
                        }
                }
        }
        for (i = 0; i < chip->num_streams; i++)
                chip->azx_dev[i].irq_pending = 0;
        spin_unlock_irq(&chip->reg_lock);
-       flush_scheduled_work();
 }
 
 static struct snd_pcm_ops azx_pcm_ops = {