David Brownell <[email protected]> writes:

> From: David Brownell <[email protected]>
>
> This shrinks the object size of davinci_mmc by about a quarter,
> ripping out stuff that was issuing all kinds of commands behind
> the back of the MMC core (evidently for card detect purposes).
>
> That's stuff that needs to be ripped out before this driver can go
> into mainline, obviously; good to remove it ASAP.
>
> This has one immediate positive effect:  cards which previously could
> not be enumerated on a dm355evm can now enumerate!  (After disabling
> DMA, for now.)  Which in turn let me boot a rootfs from an SD card ...
>
> There still seems to be state kept around after card removal, which
> prevents a second card from enumerating after removing the first one.
> Also, the MMC core failed when enumerating an MMC card; odd!
>
> (Plus fix two broken debug messages:  voltages use a bitmask, and
> newlines don't belong in the *middle* of messages.)
>
> Signed-off-by: David Brownell <[email protected]>

Thanks, applied.

> ---
> NOT YET TESTED ON DM6446 ... lightly tested on DM355 by booting
> and pulling about 85 MBytes of Debian updates over the net.  It's
> as if it were usable now.  :)

I did a basic on dm6446 and it works as well as before.

Kevin

>  drivers/mmc/host/davinci_mmc.c |  312 +++------------------------------------
>  drivers/mmc/host/davinci_mmc.h |   32 ----
>  2 files changed, 28 insertions(+), 316 deletions(-)
>
> --- a/drivers/mmc/host/davinci_mmc.c
> +++ b/drivers/mmc/host/davinci_mmc.c
> @@ -33,8 +33,6 @@
>  #include <linux/clk.h>
>  #include <linux/err.h>
>  #include <linux/mmc/host.h>
> -#include <linux/mmc/card.h>
> -#include <linux/mmc/mmc.h>
>  #include <linux/io.h>
>  #include <linux/irq.h>
>  #include <linux/delay.h>
> @@ -79,7 +77,6 @@ static void mmc_davinci_start_command(st
>       u32 resp_type = 0;
>       u32 cmd_type = 0;
>       u32 im_val;
> -     unsigned long flags;
>  
>       dev_dbg(mmc_dev(host->mmc), "CMD%d, arg 0x%08x%s\n",
>               cmd->opcode, cmd->arg,
> @@ -215,23 +212,6 @@ static void mmc_davinci_start_command(st
>               /* Fill the FIFO for Tx */
>               davinci_fifo_data_trans(host, 32);
>  
> -     if (cmd->opcode == 7) {
> -             spin_lock_irqsave(&host->lock, flags);
> -             host->is_card_removed = 0;
> -             host->new_card_state = 1;
> -             host->is_card_initialized = 1;
> -             host->old_card_state = host->new_card_state;
> -             host->is_init_progress = 0;
> -             spin_unlock_irqrestore(&host->lock, flags);
> -     }
> -     if (cmd->opcode == 1 || cmd->opcode == 41) {
> -             spin_lock_irqsave(&host->lock, flags);
> -             host->is_card_initialized = 0;
> -             host->is_init_progress = 1;
> -             spin_unlock_irqrestore(&host->lock, flags);
> -     }
> -
> -     host->is_core_command = 1;
>       writel(cmd->arg, host->base + DAVINCI_MMCARGHL);
>       writel(cmd_reg,  host->base + DAVINCI_MMCCMD);
>       writel(im_val, host->base + DAVINCI_MMCIM);
> @@ -325,15 +305,6 @@ static void davinci_fifo_data_trans(stru
>       host->buffer = p;
>  }
>  
> -static void davinci_reinit_chan(struct mmc_davinci_host *host)
> -{
> -     davinci_stop_dma(host->txdma);
> -     davinci_clean_channel(host->txdma);
> -
> -     davinci_stop_dma(host->rxdma);
> -     davinci_clean_channel(host->rxdma);
> -}
> -
>  static void davinci_abort_dma(struct mmc_davinci_host *host)
>  {
>       int sync_dev = 0;
> @@ -718,51 +689,31 @@ static void mmc_davinci_sg_to_buf(struct
>               host->buffer_bytes_left = host->bytes_left;
>  }
>  
> -static inline void wait_on_data(struct mmc_davinci_host *host)
> +static void mmc_davinci_request(struct mmc_host *mmc, struct mmc_request 
> *req)
>  {
> +     struct mmc_davinci_host *host = mmc_priv(mmc);
>       unsigned long timeout = jiffies + msecs_to_jiffies(900);
> +     u32 mmcst1 = 0;
>  
> +     /* Card may still be sending BUSY after a previous operation,
> +      * typically some kind of write.  If so, we can't proceed yet.
> +      */
>       while (time_before(jiffies, timeout)) {
> -             if (!(readl(host->base + DAVINCI_MMCST1) & MMCST1_BUSY))
> -                     return;
> -
> +             mmcst1  = readl(host->base + DAVINCI_MMCST1);
> +             if (!(mmcst1 & MMCST1_BUSY))
> +                     break;
>               cpu_relax();
>       }
> -
> -     dev_warn(mmc_dev(host->mmc), "ERROR: TOUT waiting for BUSY\n");
> -}
> -
> -static void mmc_davinci_request(struct mmc_host *mmc, struct mmc_request 
> *req)
> -{
> -     struct mmc_davinci_host *host = mmc_priv(mmc);
> -     unsigned long flags;
> -
> -     if (host->is_card_removed) {
> -             if (req->cmd) {
> -                     req->cmd->error = -ETIMEDOUT;
> -                     mmc_request_done(mmc, req);
> -             }
> -             dev_dbg(mmc_dev(host->mmc),
> -                     "From code segment excuted when card removed\n");
> +     if (mmcst1 & MMCST1_BUSY) {
> +             dev_err(mmc_dev(host->mmc), "still BUSY? bad ... \n");
> +             req->cmd->error = -ETIMEDOUT;
> +             mmc_request_done(mmc, req);
>               return;
>       }
>  
> -     wait_on_data(host);
> -
> -     if (!host->is_card_detect_progress) {
> -             spin_lock_irqsave(&host->lock, flags);
> -             host->is_card_busy = 1;
> -             spin_unlock_irqrestore(&host->lock, flags);
> -             host->do_dma = 0;
> -             mmc_davinci_prepare_data(host, req);
> -             mmc_davinci_start_command(host, req->cmd);
> -     } else {
> -             /* Queue up the request as card dectection is being excuted */
> -             host->que_mmc_request = req;
> -             spin_lock_irqsave(&host->lock, flags);
> -             host->is_req_queued_up = 1;
> -             spin_unlock_irqrestore(&host->lock, flags);
> -     }
> +     host->do_dma = 0;
> +     mmc_davinci_prepare_data(host, req);
> +     mmc_davinci_start_command(host, req->cmd);
>  }
>  
>  static unsigned int calculate_freq_for_card(struct mmc_davinci_host *host,
> @@ -793,11 +744,11 @@ static void mmc_davinci_set_ios(struct m
>  
>       cpu_arm_clk = host->mmc_input_clk;
>       dev_dbg(mmc_dev(host->mmc),
> -             "clock %dHz busmode %d powermode %d Vdd %d.%02d\r\n",
> +             "clock %dHz busmode %d powermode %d Vdd %04x\r\n",
>               ios->clock, ios->bus_mode, ios->power_mode,
> -             ios->vdd / 100, ios->vdd % 100);
> +             ios->vdd);
>       if (ios->bus_width == MMC_BUS_WIDTH_4) {
> -             dev_dbg(mmc_dev(host->mmc), "\nEnabling 4 bit mode\n");
> +             dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
>               writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_WIDTH_4_BIT,
>                       host->base + DAVINCI_MMCCTL);
>       } else {
> @@ -840,13 +791,13 @@ static void mmc_davinci_set_ios(struct m
>                               MMCSD_EVENT_EOFCMD))
>                       cpu_relax();
>       }
> +
> +     /* FIXME on power OFF, reset things ... */
>  }
>  
>  static void
>  mmc_davinci_xfer_done(struct mmc_davinci_host *host, struct mmc_data *data)
>  {
> -     unsigned long flags;
> -
>       host->data = NULL;
>       host->data_dir = DAVINCI_MMC_DATADIR_NONE;
>       if (data->error == 0)
> @@ -862,17 +813,11 @@ mmc_davinci_xfer_done(struct mmc_davinci
>       }
>  
>       if (data->error == -ETIMEDOUT) {
> -             spin_lock_irqsave(&host->lock, flags);
> -             host->is_card_busy = 0;
> -             spin_unlock_irqrestore(&host->lock, flags);
>               mmc_request_done(host->mmc, data->mrq);
>               return;
>       }
>  
>       if (!data->stop) {
> -             spin_lock_irqsave(&host->lock, flags);
> -             host->is_card_busy = 0;
> -             spin_unlock_irqrestore(&host->lock, flags);
>               mmc_request_done(host->mmc, data->mrq);
>               return;
>       }
> @@ -882,7 +827,6 @@ mmc_davinci_xfer_done(struct mmc_davinci
>  static void mmc_davinci_cmd_done(struct mmc_davinci_host *host,
>                                struct mmc_command *cmd)
>  {
> -     unsigned long flags;
>       host->cmd = NULL;
>  
>       if (!cmd) {
> @@ -907,9 +851,6 @@ static void mmc_davinci_cmd_done(struct 
>       if (host->data == NULL || cmd->error) {
>               if (cmd->error == -ETIMEDOUT)
>                       cmd->mrq->cmd->retries = 0;
> -             spin_lock_irqsave(&host->lock, flags);
> -             host->is_card_busy = 0;
> -             spin_unlock_irqrestore(&host->lock, flags);
>               mmc_request_done(host->mmc, cmd->mrq);
>       }
>  }
> @@ -920,17 +861,6 @@ static inline int handle_core_command(
>       int end_command = 0;
>       int end_transfer = 0;
>       unsigned int qstatus;
> -     unsigned long flags;
> -
> -     if ((host->is_card_initialized) && (host->new_card_state == 0)) {
> -             if (host->cmd) {
> -                     host->cmd->error = -ETIMEDOUT;
> -                     mmc_davinci_cmd_done(host, host->cmd);
> -             }
> -             dev_dbg(mmc_dev(host->mmc), "From code segment "
> -                     "excuted when card removed\n");
> -             return -1;
> -     }
>  
>       qstatus = status;
>       while (1) {
> @@ -976,13 +906,8 @@ static inline int handle_core_command(
>  
>       if (qstatus & MMCSD_EVENT_ERROR_DATATIMEOUT) {
>               /* Data timeout */
> -             if (host->data && host->new_card_state != 0) {
> +             if (host->data) {
>                       host->data->error = -ETIMEDOUT;
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->is_card_removed = 1;
> -                     host->new_card_state = 0;
> -                     host->is_card_initialized = 0;
> -                     spin_unlock_irqrestore(&host->lock, flags);
>                       dev_dbg(mmc_dev(host->mmc), "MMCSD: Data timeout, "
>                               "CMD%d and status is %x\n",
>                               host->cmd->opcode, status);
> @@ -1023,18 +948,9 @@ static inline int handle_core_command(
>  
>               /* Command timeout */
>               if (host->cmd) {
> -                     /* Timeouts are normal in case of
> -                      * MMC_SEND_STATUS
> -                      */
> -                     if (host->cmd->opcode != MMC_ALL_SEND_CID) {
> -                             dev_dbg(mmc_dev(host->mmc), "MMCSD: CMD%d "
> -                                     "timeout, status %x\n",
> -                                     host->cmd->opcode, status);
> -                             spin_lock_irqsave(&host->lock, flags);
> -                             host->new_card_state = 0;
> -                             host->is_card_initialized = 0;
> -                             spin_unlock_irqrestore(&host->lock, flags);
> -                     }
> +                     dev_dbg(mmc_dev(host->mmc), "MMCSD: CMD%d "
> +                             "timeout, status %x\n",
> +                             host->cmd->opcode, status);
>                       host->cmd->error = -ETIMEDOUT;
>                       end_command = 1;
>               }
> @@ -1063,105 +979,11 @@ static inline int handle_core_command(
>       return 0;
>  }
>  
> -static inline void handle_other_commands(
> -             struct mmc_davinci_host *host, unsigned int status)
> -{
> -     unsigned long flags;
> -     if (host->cmd_code == 13) {
> -             if (status & MMCSD_EVENT_EOFCMD) {
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->new_card_state = 1;
> -                     spin_unlock_irqrestore(&host->lock, flags);
> -             } else {
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->is_card_removed = 1;
> -                     host->new_card_state = 0;
> -                     host->is_card_initialized = 0;
> -                     spin_unlock_irqrestore(&host->lock, flags);
> -             }
> -
> -             spin_lock_irqsave(&host->lock, flags);
> -             host->is_card_detect_progress = 0;
> -             spin_unlock_irqrestore(&host->lock, flags);
> -
> -             if (host->is_req_queued_up) {
> -                     mmc_davinci_request(host->mmc, host->que_mmc_request);
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->is_req_queued_up = 0;
> -                     spin_unlock_irqrestore(&host->lock, flags);
> -             }
> -
> -     }
> -
> -     if (host->cmd_code == 1 || host->cmd_code == 55) {
> -             if (status & MMCSD_EVENT_EOFCMD) {
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->is_card_removed = 0;
> -                     host->new_card_state = 1;
> -                     host->is_card_initialized = 0;
> -                     spin_unlock_irqrestore(&host->lock, flags);
> -             } else {
> -
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->is_card_removed = 1;
> -                     host->new_card_state = 0;
> -                     host->is_card_initialized = 0;
> -                     spin_unlock_irqrestore(&host->lock, flags);
> -             }
> -
> -             spin_lock_irqsave(&host->lock, flags);
> -             host->is_card_detect_progress = 0;
> -             spin_unlock_irqrestore(&host->lock, flags);
> -
> -             if (host->is_req_queued_up) {
> -                     mmc_davinci_request(host->mmc, host->que_mmc_request);
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->is_req_queued_up = 0;
> -                     spin_unlock_irqrestore(&host->lock, flags);
> -             }
> -     }
> -
> -     if (host->cmd_code == 0) {
> -             if (status & MMCSD_EVENT_EOFCMD) {
> -                     static int flag_sd_mmc;
> -                     host->is_core_command = 0;
> -
> -                     if (flag_sd_mmc) {
> -                             flag_sd_mmc = 0;
> -                             host->cmd_code = 1;
> -                             /* Issue cmd1 */
> -                             writel(0x80300000,
> -                                     host->base + DAVINCI_MMCARGHL);
> -                             writel(MMCCMD_RSPFMT_R3 | 1,
> -                                     host->base + DAVINCI_MMCCMD);
> -                     } else {
> -                             flag_sd_mmc = 1;
> -                             host->cmd_code = 55;
> -                             /* Issue cmd55 */
> -                             writel(0x0,
> -                                     host->base + DAVINCI_MMCARGHL);
> -                             writel(MMCCMD_RSPFMT_R1456 | 55,
> -                                     host->base + DAVINCI_MMCCMD);
> -                     }
> -
> -                     dev_dbg(mmc_dev(host->mmc),
> -                             "MMC-Probing mmc with cmd%d\n", host->cmd_code);
> -             } else {
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->new_card_state = 0;
> -                     host->is_card_initialized = 0;
> -                     host->is_card_detect_progress = 0;
> -                     spin_unlock_irqrestore(&host->lock, flags);
> -             }
> -     }
> -}
> -
>  static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
>  {
>       struct mmc_davinci_host *host = (struct mmc_davinci_host *)dev_id;
>       unsigned int status;
>  
> -     if (host->is_core_command) {
>               if (host->cmd == NULL && host->data == NULL) {
>                       status = readl(host->base + DAVINCI_MMCST0);
>                       dev_dbg(mmc_dev(host->mmc),
> @@ -1170,18 +992,13 @@ static irqreturn_t mmc_davinci_irq(int i
>                       writel(0, host->base + DAVINCI_MMCIM);
>                       return IRQ_HANDLED;
>               }
> -     }
>       do {
>               status = readl(host->base + DAVINCI_MMCST0);
>               if (status == 0)
>                       break;
>  
> -             if (host->is_core_command) {
>                       if (handle_core_command(host, status))
>                               break;
> -             } else {
> -                     handle_other_commands(host, status);
> -             }
>       } while (1);
>       return IRQ_HANDLED;
>  }
> @@ -1213,68 +1030,6 @@ static struct mmc_host_ops mmc_davinci_o
>       .get_ro = mmc_davinci_get_ro,
>  };
>  
> -static void mmc_check_card(unsigned long data)
> -{
> -     struct mmc_davinci_host *host = (struct mmc_davinci_host *)data;
> -     unsigned long flags;
> -     struct mmc_card *card = NULL;
> -
> -     if (host->mmc && host->mmc->card)
> -             card = host->mmc->card;
> -
> -     if ((!host->is_card_detect_progress) || (!host->is_init_progress)) {
> -             if (host->is_card_initialized) {
> -                     host->is_core_command = 0;
> -                     host->cmd_code = 13;
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->is_card_detect_progress = 1;
> -                     spin_unlock_irqrestore(&host->lock, flags);
> -
> -                     /* Issue cmd13 */
> -                     writel((card && mmc_card_sd(card))
> -                             ? (card->rca << 16) : 0x10000,
> -                             host->base + DAVINCI_MMCARGHL);
> -                     writel(MMCCMD_RSPFMT_R1456 | MMCCMD_PPLEN | 13,
> -                             host->base + DAVINCI_MMCCMD);
> -             } else {
> -                     host->is_core_command = 0;
> -                     host->cmd_code = 0;
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->is_card_detect_progress = 1;
> -                     spin_unlock_irqrestore(&host->lock, flags);
> -
> -                     /* Issue cmd0 */
> -                     writel(0, host->base + DAVINCI_MMCARGHL);
> -                     writel(MMCCMD_INITCK, host->base + DAVINCI_MMCCMD);
> -             }
> -             writel(MMCSD_EVENT_EOFCMD
> -                     | MMCSD_EVENT_ERROR_CMDCRC
> -                     | MMCSD_EVENT_ERROR_DATACRC
> -                     | MMCSD_EVENT_ERROR_CMDTIMEOUT
> -                     | MMCSD_EVENT_ERROR_DATATIMEOUT,
> -                     host->base + DAVINCI_MMCIM);
> -     }
> -}
> -
> -static void davinci_mmc_check_status(unsigned long data)
> -{
> -     unsigned long flags;
> -     struct mmc_davinci_host *host = (struct mmc_davinci_host *)data;
> -
> -     if (!host->is_card_busy) {
> -             if (host->old_card_state ^ host->new_card_state) {
> -                     davinci_reinit_chan(host);
> -                     init_mmcsd_host(host);
> -                     mmc_detect_change(host->mmc, 0);
> -                     spin_lock_irqsave(&host->lock, flags);
> -                     host->old_card_state = host->new_card_state;
> -                     spin_unlock_irqrestore(&host->lock, flags);
> -             } else
> -                     mmc_check_card(data);
> -     }
> -     mod_timer(&host->timer, jiffies + MULTIPILER_TO_HZ * HZ);
> -}
> -
>  static void init_mmcsd_host(struct mmc_davinci_host *host)
>  {
>       /* DAT line portion is diabled and in reset state */
> @@ -1347,8 +1102,6 @@ static int davinci_mmcsd_probe(struct pl
>       if (!host->base)
>               goto out;
>  
> -     spin_lock_init(&host->lock);
> -
>       ret = -ENXIO;
>       host->clk = clk_get(&pdev->dev, "mmc");
>       if (IS_ERR(host->clk)) {
> @@ -1360,6 +1113,9 @@ static int davinci_mmcsd_probe(struct pl
>  
>       init_mmcsd_host(host);
>  
> +     /* REVISIT:  someday, support IRQ-driven card detection.  */
> +     mmc->caps |= MMC_CAP_NEEDS_POLL;
> +
>       if (!pdata || pdata->wires == 4 || pdata->wires == 0)
>               mmc->caps |= MMC_CAP_4_BIT_DATA;
>  
> @@ -1407,10 +1163,6 @@ static int davinci_mmcsd_probe(struct pl
>  
>       host->use_dma = mmcsd_cfg.use_dma;
>       host->irq = irq;
> -     host->sd_support = 1;
> -
> -     setup_timer(&host->timer, davinci_mmc_check_status,
> -                     (unsigned long)host);
>  
>       platform_set_drvdata(pdev, host);
>  
> @@ -1422,9 +1174,6 @@ static int davinci_mmcsd_probe(struct pl
>       if (ret)
>               goto out;
>  
> -     /* start probing for card */
> -     mod_timer(&host->timer, jiffies + MULTIPILER_TO_HZ * HZ);
> -
>       dev_info(mmc_dev(host->mmc), "Using %s, %d-bit mode\n",
>               mmcsd_cfg.use_dma ? "DMA" : "PIO",
>               (mmc->caps & MMC_CAP_4_BIT_DATA) ? 4 : 1);
> @@ -1458,14 +1207,9 @@ out:
>  static int davinci_mmcsd_remove(struct platform_device *pdev)
>  {
>       struct mmc_davinci_host *host = platform_get_drvdata(pdev);
> -     unsigned long flags;
>  
>       platform_set_drvdata(pdev, NULL);
>       if (host) {
> -             spin_lock_irqsave(&host->lock, flags);
> -             del_timer(&host->timer);
> -             spin_unlock_irqrestore(&host->lock, flags);
> -
>               mmc_remove_host(host->mmc);
>               free_irq(host->irq, host);
>  
> --- a/drivers/mmc/host/davinci_mmc.h
> +++ b/drivers/mmc/host/davinci_mmc.h
> @@ -182,13 +182,6 @@ struct mmc_davinci_host {
>       bool use_dma;
>       bool do_dma;
>  
> -     struct timer_list timer;
> -     unsigned int is_core_command:1;
> -     unsigned int cmd_code;
> -     unsigned int old_card_state:1;
> -
> -     unsigned char sd_support:1;
> -
>       struct edma_ch_mmcsd edma_ch_details;
>  
>       unsigned int sg_len;
> @@ -198,33 +191,8 @@ struct mmc_davinci_host {
>       unsigned int option_read;
>       unsigned int option_write;
>  
> -     /* Indicates if card being used currently by linux core or not */
> -     unsigned int is_card_busy:1;
> -
> -     /* Indicates if card probe(detection) is currently in progress */
> -     unsigned int is_card_detect_progress:1;
> -
> -     /* Indicates if core is currently initializing the card or not */
> -     unsigned int is_init_progress:1;
> -
> -     /* Indicate whether core request has been queued up or not because
> -      * request has come when card detection/probe was in progress
> -      */
> -     unsigned int is_req_queued_up:1;
> -
>       /* data structure to queue one request */
>       struct mmc_request *que_mmc_request;
> -
> -     /* tells whether card is initialized or not */
> -     unsigned is_card_initialized:1;
> -
> -     /* tells current state of card */
> -     unsigned int new_card_state:1;
> -
> -     unsigned int is_card_removed:1;
> -
> -     /* protect against mmc_check_card */
> -     spinlock_t lock;
>  };
>  
>  struct mmcsd_config_def {
>
> _______________________________________________
> Davinci-linux-open-source mailing list
> [email protected]
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to