Loading drivers/mmc/host/imxmmc.c +141 −160 Original line number Diff line number Diff line Loading @@ -10,20 +10,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * 2005-04-17 Pavel Pisa <pisa@cmp.felk.cvut.cz> * Changed to conform redesigned i.MX scatter gather DMA interface * * 2005-11-04 Pavel Pisa <pisa@cmp.felk.cvut.cz> * Updated for 2.6.14 kernel * * 2005-12-13 Jay Monkman <jtm@smoothsmoothie.com> * Found and corrected problems in the write path * * 2005-12-30 Pavel Pisa <pisa@cmp.felk.cvut.cz> * The event handling rewritten right way in softirq. * Added many ugly hacks and delays to overcome SDHC * deficiencies * */ #include <linux/module.h> Loading @@ -37,9 +23,9 @@ #include <linux/mmc/card.h> #include <linux/delay.h> #include <linux/clk.h> #include <linux/io.h> #include <asm/dma.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/sizes.h> #include <mach/mmc.h> Loading Loading @@ -74,7 +60,7 @@ struct imxmci_host { struct tasklet_struct tasklet; unsigned int status_reg; unsigned long pending_events; /* Next to fields are there for CPU driven transfers to overcome SDHC deficiencies */ /* Next two fields are there for CPU driven transfers to overcome SDHC deficiencies */ u16 *data_ptr; unsigned int data_cnt; atomic_t stuck_timeout; Loading Loading @@ -202,6 +188,7 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host, int timeout, const char *where) { int loops = 0; while (!(*pstat & stat_mask)) { loops += 2; if (loops >= timeout) { Loading Loading @@ -317,10 +304,9 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events); /* start DMA engine for read, write is delayed after initial response */ if (host->dma_dir == DMA_FROM_DEVICE) { if (host->dma_dir == DMA_FROM_DEVICE) imx_dma_enable(host->dma); } } static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, unsigned int cmdat) { Loading Loading @@ -464,9 +450,9 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) if (cmd->flags & MMC_RSP_PRESENT) { if (cmd->flags & MMC_RSP_136) { for (i = 0; i < 4; i++) { u32 a = MMC_RES_FIFO & 0xffff; u32 b = MMC_RES_FIFO & 0xffff; cmd->resp[i] = a<<16 | b; u32 d = MMC_RES_FIFO & 0xffff; u32 e = MMC_RES_FIFO & 0xffff; cmd->resp[i] = d << 16 | e; } } else { a = MMC_RES_FIFO & 0xffff; Loading Loading @@ -497,10 +483,9 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) return 0; } if(test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) { if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) imx_dma_enable(host->dma); } } } else { struct mmc_request *req; imxmci_stop_clock(host); Loading @@ -509,12 +494,11 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) if (data) imxmci_finish_data(host, stat); if( req ) { if (req) imxmci_finish_request(host, req); } else { else dev_warn(mmc_dev(host->mmc), "imxmci_cmd_done: no request to finish\n"); } } return 1; } Loading @@ -535,12 +519,11 @@ static int imxmci_data_done(struct imxmci_host *host, unsigned int stat) } else { struct mmc_request *req; req = host->req; if( req ) { if (req) imxmci_finish_request(host, req); } else { else dev_warn(mmc_dev(host->mmc), "imxmci_data_done: no request to finish\n"); } } return 1; } Loading Loading @@ -748,11 +731,10 @@ static void imxmci_tasklet_fnc(unsigned long data) /* Same as above */ stat |= host->status_reg; if(host->dma_dir == DMA_TO_DEVICE) { if (host->dma_dir == DMA_TO_DEVICE) data_dir_mask = STATUS_WRITE_OP_DONE; } else { else data_dir_mask = STATUS_DATA_TRANS_DONE; } if (stat & data_dir_mask) { clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events); Loading Loading @@ -796,10 +778,9 @@ static void imxmci_request(struct mmc_host *mmc, struct mmc_request *req) if (req->data->flags & MMC_DATA_WRITE) cmdat |= CMD_DAT_CONT_WRITE; if (req->data->flags & MMC_DATA_STREAM) { if (req->data->flags & MMC_DATA_STREAM) cmdat |= CMD_DAT_CONT_STREAM_BLOCK; } } imxmci_start_cmd(host, req->cmd, cmdat); } Loading Loading
drivers/mmc/host/imxmmc.c +141 −160 Original line number Diff line number Diff line Loading @@ -10,20 +10,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * 2005-04-17 Pavel Pisa <pisa@cmp.felk.cvut.cz> * Changed to conform redesigned i.MX scatter gather DMA interface * * 2005-11-04 Pavel Pisa <pisa@cmp.felk.cvut.cz> * Updated for 2.6.14 kernel * * 2005-12-13 Jay Monkman <jtm@smoothsmoothie.com> * Found and corrected problems in the write path * * 2005-12-30 Pavel Pisa <pisa@cmp.felk.cvut.cz> * The event handling rewritten right way in softirq. * Added many ugly hacks and delays to overcome SDHC * deficiencies * */ #include <linux/module.h> Loading @@ -37,9 +23,9 @@ #include <linux/mmc/card.h> #include <linux/delay.h> #include <linux/clk.h> #include <linux/io.h> #include <asm/dma.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/sizes.h> #include <mach/mmc.h> Loading Loading @@ -74,7 +60,7 @@ struct imxmci_host { struct tasklet_struct tasklet; unsigned int status_reg; unsigned long pending_events; /* Next to fields are there for CPU driven transfers to overcome SDHC deficiencies */ /* Next two fields are there for CPU driven transfers to overcome SDHC deficiencies */ u16 *data_ptr; unsigned int data_cnt; atomic_t stuck_timeout; Loading Loading @@ -202,6 +188,7 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host, int timeout, const char *where) { int loops = 0; while (!(*pstat & stat_mask)) { loops += 2; if (loops >= timeout) { Loading Loading @@ -317,10 +304,9 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events); /* start DMA engine for read, write is delayed after initial response */ if (host->dma_dir == DMA_FROM_DEVICE) { if (host->dma_dir == DMA_FROM_DEVICE) imx_dma_enable(host->dma); } } static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, unsigned int cmdat) { Loading Loading @@ -464,9 +450,9 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) if (cmd->flags & MMC_RSP_PRESENT) { if (cmd->flags & MMC_RSP_136) { for (i = 0; i < 4; i++) { u32 a = MMC_RES_FIFO & 0xffff; u32 b = MMC_RES_FIFO & 0xffff; cmd->resp[i] = a<<16 | b; u32 d = MMC_RES_FIFO & 0xffff; u32 e = MMC_RES_FIFO & 0xffff; cmd->resp[i] = d << 16 | e; } } else { a = MMC_RES_FIFO & 0xffff; Loading Loading @@ -497,10 +483,9 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) return 0; } if(test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) { if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) imx_dma_enable(host->dma); } } } else { struct mmc_request *req; imxmci_stop_clock(host); Loading @@ -509,12 +494,11 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) if (data) imxmci_finish_data(host, stat); if( req ) { if (req) imxmci_finish_request(host, req); } else { else dev_warn(mmc_dev(host->mmc), "imxmci_cmd_done: no request to finish\n"); } } return 1; } Loading @@ -535,12 +519,11 @@ static int imxmci_data_done(struct imxmci_host *host, unsigned int stat) } else { struct mmc_request *req; req = host->req; if( req ) { if (req) imxmci_finish_request(host, req); } else { else dev_warn(mmc_dev(host->mmc), "imxmci_data_done: no request to finish\n"); } } return 1; } Loading Loading @@ -748,11 +731,10 @@ static void imxmci_tasklet_fnc(unsigned long data) /* Same as above */ stat |= host->status_reg; if(host->dma_dir == DMA_TO_DEVICE) { if (host->dma_dir == DMA_TO_DEVICE) data_dir_mask = STATUS_WRITE_OP_DONE; } else { else data_dir_mask = STATUS_DATA_TRANS_DONE; } if (stat & data_dir_mask) { clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events); Loading Loading @@ -796,10 +778,9 @@ static void imxmci_request(struct mmc_host *mmc, struct mmc_request *req) if (req->data->flags & MMC_DATA_WRITE) cmdat |= CMD_DAT_CONT_WRITE; if (req->data->flags & MMC_DATA_STREAM) { if (req->data->flags & MMC_DATA_STREAM) cmdat |= CMD_DAT_CONT_STREAM_BLOCK; } } imxmci_start_cmd(host, req->cmd, cmdat); } Loading