[PATCH] mmc: mxs-mmc: add support for pre_req and post_req

Per Forlin per.forlin at linaro.org
Wed Apr 20 03:58:48 EDT 2011


On 17 April 2011 18:33, Shawn Guo <shawn.guo at linaro.org> wrote:
> pre_req() runs dma_map_sg() post_req() runs dma_unmap_sg.
> If not calling pre_req() before mxs_mmc_request(), request()
> will prepare the cache just like it did it before.
> It is optional to use pre_req() and post_req().
>
> Signed-off-by: Shawn Guo <shawn.guo at linaro.org>
> ---
>  drivers/mmc/host/mxs-mmc.c |   75 ++++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 72 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
> index 99d39a6..63c2ae2 100644
> --- a/drivers/mmc/host/mxs-mmc.c
> +++ b/drivers/mmc/host/mxs-mmc.c
> @@ -137,6 +137,10 @@
>
>  #define SSP_PIO_NUM    3
>
> +struct mxs_mmc_next {
> +       s32 cookie;
> +};
> +
>  struct mxs_mmc_host {
>        struct mmc_host                 *mmc;
>        struct mmc_request              *mrq;
> @@ -154,6 +158,7 @@ struct mxs_mmc_host {
>        struct mxs_dma_data             dma_data;
>        unsigned int                    dma_dir;
>        u32                             ssp_pio_words[SSP_PIO_NUM];
> +       struct mxs_mmc_next             next_data;
>
>        unsigned int                    version;
>        unsigned char                   bus_width;
> @@ -302,6 +307,31 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
>        return IRQ_HANDLED;
>  }
>
> +static int mxs_mmc_prep_dma_data(struct mxs_mmc_host *host,
> +                               struct mmc_data *data,
> +                               struct mxs_mmc_next *next)
> +{
> +       if (!next && data->host_cookie &&
> +           data->host_cookie != host->next_data.cookie) {
> +               printk(KERN_WARNING "[%s] invalid cookie: data->host_cookie %d"
> +                      " host->next_data.cookie %d\n",
> +                      __func__, data->host_cookie, host->next_data.cookie);
> +               data->host_cookie = 0;
> +       }
> +
> +       /* Check if next job is already prepared */
> +       if (next || (!next && data->host_cookie != host->next_data.cookie))
> +               if (dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
> +                              (data->flags & MMC_DATA_WRITE) ?
> +                              DMA_TO_DEVICE : DMA_FROM_DEVICE) == 0)
> +                       return -EINVAL;
> +
> +       if (next)
> +               data->host_cookie = ++next->cookie < 0 ? 1 : next->cookie;
> +
> +       return 0;
> +}
> +
>  static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
>        struct mxs_mmc_host *host, unsigned int append)
>  {
> @@ -312,8 +342,8 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
>
>        if (data) {
>                /* data */
> -               dma_map_sg(mmc_dev(host->mmc), data->sg,
> -                          data->sg_len, host->dma_dir);
> +               if (mxs_mmc_prep_dma_data(host, data, NULL))
> +                       return NULL;
>                sgl = data->sg;
>                sg_len = data->sg_len;
>        } else {
> @@ -328,9 +358,11 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
>                desc->callback = mxs_mmc_dma_irq_callback;
>                desc->callback_param = host;
>        } else {
> -               if (data)
> +               if (data) {
>                        dma_unmap_sg(mmc_dev(host->mmc), data->sg,
>                                     data->sg_len, host->dma_dir);
> +                       data->host_cookie = 0;
> +               }
When is dma_unmap_sg called? If host_cookie is set dma_unmap() should
only be called from post_req.
My guess is
+ if (data && !data->host_cookie) {
It looks like only dma_map is run in parallel with transfer but not
dma_unmap. This may explain the numbers.



More information about the linux-arm-kernel mailing list