Skip to content

Commit

Permalink
mmc: omap: convert to per instance workqueue
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Venkatraman S authored and cjb committed May 17, 2012
1 parent f6f4459 commit b01a4f1
Showing 1 changed file with 12 additions and 17 deletions.
29 changes: 12 additions & 17 deletions drivers/mmc/host/omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit b01a4f1

Please sign in to comment.