]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/mmc/host/sdhci.c
mmc: sdhci: Use work structs instead of tasklets
[karo-tx-linux.git] / drivers / mmc / host / sdhci.c
index f1680b80441a682a8ef0994ea7601062ba1a0c6f..53befafe8ff8efe0404559067af0e36a43c80500 100644 (file)
@@ -978,7 +978,7 @@ static void sdhci_finish_data(struct sdhci_host *host)
 
                sdhci_send_command(host, data->stop);
        } else
-               tasklet_schedule(&host->finish_tasklet);
+               schedule_work(&host->finish_work);
 }
 
 void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
@@ -1007,7 +1007,7 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
                                "inhibit bit(s).\n", mmc_hostname(host->mmc));
                        sdhci_dumpregs(host);
                        cmd->error = -EIO;
-                       tasklet_schedule(&host->finish_tasklet);
+                       schedule_work(&host->finish_work);
                        return;
                }
                timeout--;
@@ -1028,7 +1028,7 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
                pr_err("%s: Unsupported response type!\n",
                        mmc_hostname(host->mmc));
                cmd->error = -EINVAL;
-               tasklet_schedule(&host->finish_tasklet);
+               schedule_work(&host->finish_work);
                return;
        }
 
@@ -1090,7 +1090,7 @@ static void sdhci_finish_command(struct sdhci_host *host)
                        sdhci_finish_data(host);
 
                if (!host->cmd->data)
-                       tasklet_schedule(&host->finish_tasklet);
+                       schedule_work(&host->finish_work);
 
                host->cmd = NULL;
        }
@@ -1374,7 +1374,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
        if (!present || host->flags & SDHCI_DEVICE_DEAD) {
                host->mrq->cmd->error = -ENOMEDIUM;
-               tasklet_schedule(&host->finish_tasklet);
+               schedule_work(&host->finish_work);
        } else {
                u32 present_state;
 
@@ -2091,7 +2091,7 @@ static void sdhci_card_event(struct mmc_host *mmc)
                sdhci_reset(host, SDHCI_RESET_DATA);
 
                host->mrq->cmd->error = -ENOMEDIUM;
-               tasklet_schedule(&host->finish_tasklet);
+               schedule_work(&host->finish_work);
        }
 
        spin_unlock_irqrestore(&host->lock, flags);
@@ -2116,29 +2116,30 @@ static const struct mmc_host_ops sdhci_ops = {
  *                                                                           *
 \*****************************************************************************/
 
-static void sdhci_tasklet_card(unsigned long param)
+static void sdhci_card_detect_work(struct work_struct *wk)
 {
-       struct sdhci_host *host = (struct sdhci_host*)param;
+       struct sdhci_host *host = container_of(wk, struct sdhci_host,
+                                                  card_detect_work);
 
        sdhci_card_event(host->mmc);
 
        mmc_detect_change(host->mmc, msecs_to_jiffies(200));
 }
 
-static void sdhci_tasklet_finish(unsigned long param)
+static void sdhci_finish_work(struct work_struct *wk)
 {
        struct sdhci_host *host;
        unsigned long flags;
        struct mmc_request *mrq;
 
-       host = (struct sdhci_host*)param;
+       host = container_of(wk, struct sdhci_host, finish_work);
 
        spin_lock_irqsave(&host->lock, flags);
 
-        /*
-         * If this tasklet gets rescheduled while running, it will
-         * be run again afterwards but without any active request.
-         */
+       /*
+        * If this work gets rescheduled while running, it will
+        * be run again afterwards but without any active request.
+        */
        if (!host->mrq) {
                spin_unlock_irqrestore(&host->lock, flags);
                return;
@@ -2207,7 +2208,7 @@ static void sdhci_timeout_work(struct work_struct *wk)
                        else
                                host->mrq->cmd->error = -ETIMEDOUT;
 
-                       tasklet_schedule(&host->finish_tasklet);
+                       schedule_work(&host->finish_work);
                }
        }
 
@@ -2254,7 +2255,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
                host->cmd->error = -EILSEQ;
 
        if (host->cmd->error) {
-               tasklet_schedule(&host->finish_tasklet);
+               schedule_work(&host->finish_work);
                return;
        }
 
@@ -2463,7 +2464,7 @@ again:
                sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
                             SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
                intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
-               tasklet_schedule(&host->card_tasklet);
+               schedule_work(&host->card_detect_work);
        }
 
        if (intmask & SDHCI_INT_CMD_MASK) {
@@ -3210,12 +3211,10 @@ int sdhci_add_host(struct sdhci_host *host)
        mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
 
        /*
-        * Init tasklets.
+        * Init work structs.
         */
-       tasklet_init(&host->card_tasklet,
-               sdhci_tasklet_card, (unsigned long)host);
-       tasklet_init(&host->finish_tasklet,
-               sdhci_tasklet_finish, (unsigned long)host);
+       INIT_WORK(&host->card_detect_work, sdhci_card_detect_work);
+       INIT_WORK(&host->finish_work, sdhci_finish_work);
 
        INIT_DELAYED_WORK(&host->timeout_work, sdhci_timeout_work);
 
@@ -3234,7 +3233,7 @@ int sdhci_add_host(struct sdhci_host *host)
        if (ret) {
                pr_err("%s: Failed to request IRQ %d: %d\n",
                       mmc_hostname(mmc), host->irq, ret);
-               goto untasklet;
+               return ret;
        }
 
 #ifdef CONFIG_MMC_DEBUG
@@ -3276,10 +3275,6 @@ reset:
        sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
        free_irq(host->irq, host);
 #endif
-untasklet:
-       tasklet_kill(&host->card_tasklet);
-       tasklet_kill(&host->finish_tasklet);
-
        return ret;
 }
 
@@ -3299,7 +3294,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
                                " transfer!\n", mmc_hostname(host->mmc));
 
                        host->mrq->cmd->error = -ENOMEDIUM;
-                       tasklet_schedule(&host->finish_tasklet);
+                       schedule_work(&host->finish_work);
                }
 
                spin_unlock_irqrestore(&host->lock, flags);
@@ -3321,8 +3316,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 
        flush_delayed_work(&host->timeout_work);
 
-       tasklet_kill(&host->card_tasklet);
-       tasklet_kill(&host->finish_tasklet);
+       flush_work(&host->card_detect_work);
+       flush_work(&host->finish_work);
 
        if (host->vmmc) {
                regulator_disable(host->vmmc);