diff options
Diffstat (limited to 'drivers/mmc/host/omap.c')
-rw-r--r-- | drivers/mmc/host/omap.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index a8ee0df47148..c50617d03709 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -28,6 +28,7 @@ #include <linux/slab.h> #include <linux/gpio/consumer.h> #include <linux/platform_data/mmc-omap.h> +#include <linux/workqueue.h> #define OMAP_MMC_REG_CMD 0x00 @@ -105,7 +106,7 @@ struct mmc_omap_slot { u16 power_mode; unsigned int fclk_freq; - struct tasklet_struct cover_tasklet; + struct work_struct cover_bh_work; struct timer_list cover_timer; unsigned cover_open; @@ -213,7 +214,7 @@ static void mmc_omap_select_slot(struct mmc_omap_slot *slot, int claimed) host->mmc = slot->mmc; spin_unlock_irqrestore(&host->slot_lock, flags); no_claim: - del_timer(&host->clk_timer); + timer_delete(&host->clk_timer); if (host->current_slot != slot || !claimed) mmc_omap_fclk_offdelay(host->current_slot); @@ -272,7 +273,7 @@ static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled) /* Keeps clock running for at least 8 cycles on valid freq */ mod_timer(&host->clk_timer, jiffies + HZ/10); else { - del_timer(&host->clk_timer); + timer_delete(&host->clk_timer); mmc_omap_fclk_offdelay(slot); mmc_omap_fclk_enable(host, 0); } @@ -563,7 +564,7 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd) { host->cmd = NULL; - del_timer(&host->cmd_abort_timer); + timer_delete(&host->cmd_abort_timer); if (cmd->flags & MMC_RSP_PRESENT) { if (cmd->flags & MMC_RSP_136) { @@ -835,7 +836,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } if (cmd_error && host->data) { - del_timer(&host->cmd_abort_timer); + timer_delete(&host->cmd_abort_timer); host->abort = 1; OMAP_MMC_WRITE(host, IE, 0); disable_irq_nosync(host->irq); @@ -873,18 +874,18 @@ void omap_mmc_notify_cover_event(struct device *dev, int num, int is_closed) sysfs_notify(&slot->mmc->class_dev.kobj, NULL, "cover_switch"); } - tasklet_hi_schedule(&slot->cover_tasklet); + queue_work(system_bh_highpri_wq, &slot->cover_bh_work); } static void mmc_omap_cover_timer(struct timer_list *t) { struct mmc_omap_slot *slot = from_timer(slot, t, cover_timer); - tasklet_schedule(&slot->cover_tasklet); + queue_work(system_bh_wq, &slot->cover_bh_work); } -static void mmc_omap_cover_handler(struct tasklet_struct *t) +static void mmc_omap_cover_bh_handler(struct work_struct *t) { - struct mmc_omap_slot *slot = from_tasklet(slot, t, cover_tasklet); + struct mmc_omap_slot *slot = from_work(slot, t, cover_bh_work); int cover_open = mmc_omap_cover_is_open(slot); mmc_detect_change(slot->mmc, 0); @@ -1271,19 +1272,25 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) /* Check for some optional GPIO controls */ slot->vsd = devm_gpiod_get_index_optional(host->dev, "vsd", id, GPIOD_OUT_LOW); - if (IS_ERR(slot->vsd)) - return dev_err_probe(host->dev, PTR_ERR(slot->vsd), + if (IS_ERR(slot->vsd)) { + r = dev_err_probe(host->dev, PTR_ERR(slot->vsd), "error looking up VSD GPIO\n"); + goto err_free_host; + } slot->vio = devm_gpiod_get_index_optional(host->dev, "vio", id, GPIOD_OUT_LOW); - if (IS_ERR(slot->vio)) - return dev_err_probe(host->dev, PTR_ERR(slot->vio), + if (IS_ERR(slot->vio)) { + r = dev_err_probe(host->dev, PTR_ERR(slot->vio), "error looking up VIO GPIO\n"); + goto err_free_host; + } slot->cover = devm_gpiod_get_index_optional(host->dev, "cover", id, GPIOD_IN); - if (IS_ERR(slot->cover)) - return dev_err_probe(host->dev, PTR_ERR(slot->cover), + if (IS_ERR(slot->cover)) { + r = dev_err_probe(host->dev, PTR_ERR(slot->cover), "error looking up cover switch GPIO\n"); + goto err_free_host; + } host->slots[id] = slot; @@ -1314,7 +1321,7 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) if (slot->pdata->get_cover_state != NULL) { timer_setup(&slot->cover_timer, mmc_omap_cover_timer, 0); - tasklet_setup(&slot->cover_tasklet, mmc_omap_cover_handler); + INIT_WORK(&slot->cover_bh_work, mmc_omap_cover_bh_handler); } r = mmc_add_host(mmc); @@ -1333,7 +1340,7 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) &dev_attr_cover_switch); if (r < 0) goto err_remove_slot_name; - tasklet_schedule(&slot->cover_tasklet); + queue_work(system_bh_wq, &slot->cover_bh_work); } return 0; @@ -1343,6 +1350,7 @@ err_remove_slot_name: device_remove_file(&mmc->class_dev, &dev_attr_slot_name); err_remove_host: mmc_remove_host(mmc); +err_free_host: mmc_free_host(mmc); return r; } @@ -1356,8 +1364,8 @@ static void mmc_omap_remove_slot(struct mmc_omap_slot *slot) if (slot->pdata->get_cover_state != NULL) device_remove_file(&mmc->class_dev, &dev_attr_cover_switch); - tasklet_kill(&slot->cover_tasklet); - del_timer_sync(&slot->cover_timer); + cancel_work_sync(&slot->cover_bh_work); + timer_delete_sync(&slot->cover_timer); flush_workqueue(slot->host->mmc_omap_wq); mmc_remove_host(mmc); @@ -1553,7 +1561,7 @@ MODULE_DEVICE_TABLE(of, mmc_omap_match); static struct platform_driver mmc_omap_driver = { .probe = mmc_omap_probe, - .remove_new = mmc_omap_remove, + .remove = mmc_omap_remove, .driver = { .name = DRIVER_NAME, .probe_type = PROBE_PREFER_ASYNCHRONOUS, |