diff options
Diffstat (limited to 'drivers/mmc/host/atmel-mci.c')
-rw-r--r-- | drivers/mmc/host/atmel-mci.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 8199d9620075..6490df54a6f5 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -33,6 +33,7 @@ #include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/pinctrl/consumer.h> +#include <linux/workqueue.h> #include <asm/cacheflush.h> #include <asm/io.h> @@ -272,12 +273,12 @@ struct atmel_mci_dma { * EVENT_DATA_ERROR is pending. * @stop_cmdr: Value to be loaded into CMDR when the stop command is * to be sent. - * @tasklet: Tasklet running the request state machine. + * @bh_work: Work running the request state machine. * @pending_events: Bitmask of events flagged by the interrupt handler - * to be processed by the tasklet. + * to be processed by the work. * @completed_events: Bitmask of events which the state machine has * processed. - * @state: Tasklet state. + * @state: Work state. * @queue: List of slots waiting for access to the controller. * @need_clock_update: Update the clock rate before the next request. * @need_reset: Reset controller before next request. @@ -352,7 +353,7 @@ struct atmel_mci { u32 data_status; u32 stop_cmdr; - struct tasklet_struct tasklet; + struct work_struct bh_work; unsigned long pending_events; unsigned long completed_events; enum atmel_mci_state state; @@ -735,7 +736,7 @@ static void atmci_timeout_timer(struct timer_list *t) host->need_reset = 1; host->state = STATE_END_REQUEST; smp_wmb(); - tasklet_schedule(&host->tasklet); + queue_work(system_bh_wq, &host->bh_work); } static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host, @@ -958,7 +959,7 @@ static void atmci_pdc_complete(struct atmel_mci *host) dev_dbg(dev, "(%s) set pending xfer complete\n", __func__); atmci_set_pending(host, EVENT_XFER_COMPLETE); - tasklet_schedule(&host->tasklet); + queue_work(system_bh_wq, &host->bh_work); } static void atmci_dma_cleanup(struct atmel_mci *host) @@ -972,7 +973,7 @@ static void atmci_dma_cleanup(struct atmel_mci *host) } /* - * This function is called by the DMA driver from tasklet context. + * This function is called by the DMA driver from bh context. */ static void atmci_dma_complete(void *arg) { @@ -995,7 +996,7 @@ static void atmci_dma_complete(void *arg) if (data) { dev_dbg(dev, "(%s) set pending xfer complete\n", __func__); atmci_set_pending(host, EVENT_XFER_COMPLETE); - tasklet_schedule(&host->tasklet); + queue_work(system_bh_wq, &host->bh_work); /* * Regardless of what the documentation says, we have @@ -1008,7 +1009,7 @@ static void atmci_dma_complete(void *arg) * haven't seen all the potential error bits yet. * * The interrupt handler will schedule a different - * tasklet to finish things up when the data transfer + * bh work to finish things up when the data transfer * is completely done. * * We may not complete the mmc request here anyway @@ -1745,9 +1746,9 @@ static void atmci_detect_change(struct timer_list *t) } } -static void atmci_tasklet_func(struct tasklet_struct *t) +static void atmci_work_func(struct work_struct *t) { - struct atmel_mci *host = from_tasklet(host, t, tasklet); + struct atmel_mci *host = from_work(host, t, bh_work); struct mmc_request *mrq = host->mrq; struct mmc_data *data = host->data; struct device *dev = host->dev; @@ -1759,7 +1760,7 @@ static void atmci_tasklet_func(struct tasklet_struct *t) state = host->state; - dev_vdbg(dev, "tasklet: state %u pending/completed/mask %lx/%lx/%x\n", + dev_vdbg(dev, "bh_work: state %u pending/completed/mask %lx/%lx/%x\n", state, host->pending_events, host->completed_events, atmci_readl(host, ATMCI_IMR)); @@ -2118,7 +2119,7 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id) dev_dbg(dev, "set pending data error\n"); smp_wmb(); atmci_set_pending(host, EVENT_DATA_ERROR); - tasklet_schedule(&host->tasklet); + queue_work(system_bh_wq, &host->bh_work); } if (pending & ATMCI_TXBUFE) { @@ -2187,7 +2188,7 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id) smp_wmb(); dev_dbg(dev, "set pending notbusy\n"); atmci_set_pending(host, EVENT_NOTBUSY); - tasklet_schedule(&host->tasklet); + queue_work(system_bh_wq, &host->bh_work); } if (pending & ATMCI_NOTBUSY) { @@ -2196,7 +2197,7 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id) smp_wmb(); dev_dbg(dev, "set pending notbusy\n"); atmci_set_pending(host, EVENT_NOTBUSY); - tasklet_schedule(&host->tasklet); + queue_work(system_bh_wq, &host->bh_work); } if (pending & ATMCI_RXRDY) @@ -2211,7 +2212,7 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id) smp_wmb(); dev_dbg(dev, "set pending cmd rdy\n"); atmci_set_pending(host, EVENT_CMD_RDY); - tasklet_schedule(&host->tasklet); + queue_work(system_bh_wq, &host->bh_work); } if (pending & (ATMCI_SDIOIRQA | ATMCI_SDIOIRQB)) @@ -2487,7 +2488,7 @@ static int atmci_probe(struct platform_device *pdev) host->mapbase = regs->start; - tasklet_setup(&host->tasklet, atmci_tasklet_func); + INIT_WORK(&host->bh_work, atmci_work_func); ret = request_irq(irq, atmci_interrupt, 0, dev_name(dev), host); if (ret) { |