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]>
---
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.  :)

 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

Reply via email to