]> git.karo-electronics.de Git - linux-beck.git/commitdiff
mmc: omap: convert to per instance workqueue
authorVenkatraman S <svenkatr@ti.com>
Tue, 8 May 2012 11:35:33 +0000 (17:05 +0530)
committerChris Ball <cjb@laptop.org>
Thu, 17 May 2012 12:25:41 +0000 (08:25 -0400)
Currently, a global mmc_omap_wq is created for all instances of omap
hosts, which can lead to races and doesn't lend itself to unload the
module cleanly.  Instead, create per instance workqueue and remove
 the common workqueue.

Signed-off-by: Venkatraman S <svenkatr@ti.com>
Acked-by: Balaji T K <balajitk@ti.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
drivers/mmc/host/omap.c

index 887c0e598cf3308d53f0324fba71176fb65d060b..2d7628eee3d3a7d7253764d9a7e14ed09e85e0c8 100644 (file)
@@ -169,11 +169,11 @@ struct mmc_omap_host {
        struct timer_list       clk_timer;
        spinlock_t              clk_lock;     /* for changing enabled state */
        unsigned int            fclk_enabled:1;
+       struct workqueue_struct *mmc_omap_wq;
 
        struct omap_mmc_platform_data *pdata;
 };
 
-static struct workqueue_struct *mmc_omap_wq;
 
 static void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
 {
@@ -291,7 +291,7 @@ static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled)
                host->next_slot = new_slot;
                host->mmc = new_slot->mmc;
                spin_unlock_irqrestore(&host->slot_lock, flags);
-               queue_work(mmc_omap_wq, &host->slot_release_work);
+               queue_work(host->mmc_omap_wq, &host->slot_release_work);
                return;
        }
 
@@ -459,7 +459,7 @@ mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
        }
 
        host->stop_data = data;
-       queue_work(mmc_omap_wq, &host->send_stop_work);
+       queue_work(host->mmc_omap_wq, &host->send_stop_work);
 }
 
 static void
@@ -639,7 +639,7 @@ mmc_omap_cmd_timer(unsigned long data)
                OMAP_MMC_WRITE(host, IE, 0);
                disable_irq(host->irq);
                host->abort = 1;
-               queue_work(mmc_omap_wq, &host->cmd_abort_work);
+               queue_work(host->mmc_omap_wq, &host->cmd_abort_work);
        }
        spin_unlock_irqrestore(&host->slot_lock, flags);
 }
@@ -828,7 +828,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
                host->abort = 1;
                OMAP_MMC_WRITE(host, IE, 0);
                disable_irq_nosync(host->irq);
-               queue_work(mmc_omap_wq, &host->cmd_abort_work);
+               queue_work(host->mmc_omap_wq, &host->cmd_abort_work);
                return IRQ_HANDLED;
        }
 
@@ -1389,7 +1389,7 @@ static void mmc_omap_remove_slot(struct mmc_omap_slot *slot)
 
        tasklet_kill(&slot->cover_tasklet);
        del_timer_sync(&slot->cover_timer);
-       flush_workqueue(mmc_omap_wq);
+       flush_workqueue(slot->host->mmc_omap_wq);
 
        mmc_remove_host(mmc);
        mmc_free_host(mmc);
@@ -1497,6 +1497,10 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
 
        host->reg_shift = (cpu_is_omap7xx() ? 1 : 2);
 
+       host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0);
+       if (!host->mmc_omap_wq)
+               goto err_plat_cleanup;
+
        return 0;
 
 err_plat_cleanup:
@@ -1542,6 +1546,7 @@ static int mmc_omap_remove(struct platform_device *pdev)
        iounmap(host->virt_base);
        release_mem_region(pdev->resource[0].start,
                           pdev->resource[0].end - pdev->resource[0].start + 1);
+       destroy_workqueue(host->mmc_omap_wq);
 
        kfree(host);
 
@@ -1610,22 +1615,12 @@ static struct platform_driver mmc_omap_driver = {
 
 static int __init mmc_omap_init(void)
 {
-       int ret;
-
-       mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0);
-       if (!mmc_omap_wq)
-               return -ENOMEM;
-
-       ret = platform_driver_probe(&mmc_omap_driver, mmc_omap_probe);
-       if (ret)
-               destroy_workqueue(mmc_omap_wq);
-       return ret;
+       return platform_driver_probe(&mmc_omap_driver, mmc_omap_probe);
 }
 
 static void __exit mmc_omap_exit(void)
 {
        platform_driver_unregister(&mmc_omap_driver);
-       destroy_workqueue(mmc_omap_wq);
 }
 
 module_init(mmc_omap_init);