⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻
📖 第 1 页 / 共 3 页
字号:
--- omap_hsmmc.c	2008-07-04 21:26:18.000000000 +0530+++ /home/khasim/psp_release/linux/kernel_org/2.6_kernel/drivers/mmc/host/omap_hsmmc.c	2008-06-26 15:59:51.000000000 +0530@@ -42,6 +42,7 @@ #include <asm/arch/clock.h> #include <asm/semaphore.h> #include "omap_hsmmc.h"+#include <asm/scatterlist.h>  #ifdef CONFIG_PM #include <linux/notifier.h>@@ -87,8 +88,10 @@ #define OMAP_MMC_SYSCONFIG_LVL2	0x2 #endif /* #ifdef AGGR_PM_CAP */ -#if defined(CONFIG_MACH_OMAP_2430SDP) || defined(CONFIG_MACH_OMAP_3430SDP) || \-    defined(CONFIG_MACH_OMAP_3430LABRADOR) || defined(CONFIG_MACH_OMAP3_BEAGLE)+#if defined(CONFIG_MACH_OMAP_2430SDP) || \+	defined(CONFIG_MACH_OMAP_3430SDP) || \+	defined(CONFIG_MACH_OMAP_3430LABRADOR) || \+	defined(CONFIG_MACH_OMAP3EVM) extern int enable_mmc_power(int slot); extern int disable_mmc_power(int slot); extern int mask_carddetect_int(int slot);@@ -104,6 +107,9 @@ DEVICE_ATTR(mmc_cover_switch, S_IRUGO, m DEVICE_ATTR(mmc_card_detect, S_IWUSR, NULL, set_mmc_carddetect); #endif +#define MMC_CARD_NONE 4+#define MAX_CRC_RETRY 1+ struct mmc_omap_host *saved_host1, *saved_host2;  struct mmc_omap_host {@@ -133,9 +139,29 @@ struct mmc_omap_host { 	u32		bytesleft; 	int		use_dma, dma_ch; 	unsigned int	dma_len;+	unsigned int	sg_dma_len; 	unsigned int	dma_dir;+	int chain_id;+	struct omap_dma_channel_params params;+	u32 chains_requested;/* Number of chains to be requested */+	u32 extra_chain_reqd;/* if there is a need of last chaining*/+	u32 no_of_chain_reqd;/*No of times callback called*/+	u32 current_cb_cnt;+	int brs_received;+	int dma_done;+	int dma_is_read;+	spinlock_t dma_lock;+	unsigned int sg_len;+	int sg_idx;+	u32 buffer_bytes_left;+	u32 total_bytes_left; 	struct		work_struct mmc_carddetect_work; 	int		initstream;+	/*Added for CRC retry*/+	bool card_detected;+	u32 rca, mod_addr, org_addr;+	int is_high_capacity;+	int flag_err, cmd_12,cmd_13, crc_retry; };  #ifdef CONFIG_OMAP34XX_OFFMODE@@ -164,6 +190,12 @@ static int gptfclk_counter; #endif /* #ifdef CONFIG_MMC_OMAP3430 */  static int mmc_clk_counter [NO_OF_MMC_HOSTS];+#define OMAP_MMC_STAT_BRR						  1 << 5+#define OMAP_MMC_STAT_BWR						  1 << 4+#define NO_OF_DMA_CHAINS_USED 2//This will work  with 2 chains currently++static void mmc_chain_dma(struct mmc_omap_host *host, struct mmc_data *data);+static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data);  #ifdef AGGR_PM_CAP static int omap_mmc_sysconfig (struct mmc_omap_host *host, int level)@@ -377,6 +409,28 @@ static void send_init_stream(struct mmc_ 	enable_irq(host->irq); } ++/*+ * Configure the resptype, cmdtype and send the given command to the card+ */+static void+mmc_omap_start_command18(struct mmc_omap_host *host, struct mmc_command *cmd)+{+	int  cmdreg = 0, resptype = 0, cmdtype = 0;++	mmc_clk_enable_aggressive(host);+	/* Clear status bits and enable interrupts */+	OMAP_HSMMC_WRITE(host->base, STAT, OMAP_HSMMC_STAT_CLEAR);++	resptype = 2;+	cmdreg = (MMC_READ_MULTIPLE_BLOCK << 24) | (resptype << 16) | (cmdtype << 22);+	cmdreg |= DP_SELECT | DDIR | MSBS | BCE | DMA_EN;+	OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);+	OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);+	OMAP_HSMMC_WRITE(host->base, ARG, host->mod_addr);+	OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);+}+ /*  * Configure the resptype, cmdtype and send the given command to the card  */@@ -419,6 +473,11 @@ mmc_omap_start_command(struct mmc_omap_h 	}  	cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22);+	if (cmd->opcode == MMC_SEND_CSD)+		host->rca = cmd->arg;+	if (cmd->opcode == MMC_READ_MULTIPLE_BLOCK)+		host->org_addr = cmd->arg;+  	if (cmd->opcode == MMC_READ_SINGLE_BLOCK 		|| cmd->opcode == MMC_READ_MULTIPLE_BLOCK@@ -452,14 +511,14 @@ mmc_omap_start_command(struct mmc_omap_h 		}  		if (cmd->arg & OMAP_SDIO_READ) {-#ifdef  CONFIG_OMAP_SDIO_NON_DMA_MODE+#ifdef	CONFIG_OMAP_SDIO_NON_DMA_MODE 			cmdreg |= DP_SELECT; #else 			cmdreg |= DP_SELECT | DMA_EN | BCE | MSBS; #endif 			cmdreg &= ~(DDIR); 		} else {-#ifdef  CONFIG_OMAP_SDIO_NON_DMA_MODE+#ifdef	CONFIG_OMAP_SDIO_NON_DMA_MODE 			cmdreg |= DP_SELECT | DDIR; #else 			cmdreg |= DP_SELECT | DDIR | DMA_EN | BCE | MSBS;@@ -556,17 +615,24 @@ sdio_omap_xfer_done(struct mmc_omap_host static void mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data) {-	host->data = NULL;--	if (host->use_dma && host->dma_ch != -1) {-		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,+	if(host->use_dma)+	{+		/* Un-map the memory required for DMA */+		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, 			host->dma_dir); 	} +	/* Reset the variables as transfer is complete */+	host->data = NULL;+	host->sg_len = 0;+	host->sg_dma_len = 0;+ 	host->datadir = OMAP_MMC_DATADIR_NONE;  	if (data->error == MMC_ERR_NONE) 		data->bytes_xfered += data->blocks * (data->blksz);+	else+		data->bytes_xfered = 0;  	mmc_clk_disable_aggressive(host); @@ -575,10 +641,51 @@ mmc_omap_xfer_done(struct mmc_omap_host  		mmc_request_done(host->mmc, data->mrq); 		return; 	}-+	/* Send the stop command. Remember FCLK is not stopped before this call */ 	mmc_omap_start_command(host, data->stop); } ++static void+mmc_omap_end_of_data(struct mmc_omap_host *host, struct mmc_data *data)+{+	unsigned long flags;+	int done;++	if (!host->use_dma) {+		mmc_omap_xfer_done(host, data);+		return;+	}+	done = 0;+	spin_lock_irqsave(&host->dma_lock, flags);+	if (host->dma_done)+		done = 1;+	else+		host->brs_received = 1;+	spin_unlock_irqrestore(&host->dma_lock, flags);++	if (done)+		mmc_omap_xfer_done(host, data);+}+++static void+mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data)+{+	unsigned long flags;+	int done;++	done = 0;+	spin_lock_irqsave(&host->dma_lock, flags);+	if (host->brs_received)+		done = 1;+	else+		host->dma_done = 1;+	spin_unlock_irqrestore(&host->dma_lock, flags);+	if (done)+		mmc_omap_xfer_done(host, data);+}+ /*  * Notify the core about command completion  */@@ -586,7 +693,6 @@ static void mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd) { 	host->cmd = NULL;- 	if (cmd->flags & MMC_RSP_PRESENT) { 		if (cmd->flags & MMC_RSP_136) { 			/* response type 2 */@@ -599,6 +705,29 @@ mmc_omap_cmd_done(struct mmc_omap_host * 			cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10); 		} 	}+	if(cmd->opcode == SD_APP_OP_COND)+	{+		if(cmd->resp[0] & 0x40000000)+		{+			host->is_high_capacity = 1;+		}+		else+		{+			host->is_high_capacity = 0;+		}+	}+	if(cmd->opcode == MMC_SEND_OP_COND)+	{+		if(cmd->resp[0] & 0x40000000)+		{+			host->is_high_capacity = 1;+		}+		else+		{+			host->is_high_capacity = 0;+		}+	}+ #ifdef CONFIG_OMAP_SDIO 	if (host->mmc->mode == MMC_MODE_SDIO) { 		if (host->sdiodata == NULL || cmd->error != MMC_ERR_NONE) {@@ -636,13 +765,27 @@ static void mmc_dma_cleanup(struct mmc_o  	host->data->error |= MMC_ERR_TIMEOUT; -	if (host->use_dma && host->dma_ch != -1) {-		dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,-			host->dma_dir);-		dma_ch = host->dma_ch;-		host->dma_ch = -1;-		omap_free_dma(dma_ch);-		up(&host->sem);+	if(host->mmc->mode == MMC_MODE_SDIO)+	{+		if (host->use_dma && host->dma_ch != -1) {+			dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,+				host->dma_dir);+			dma_ch = host->dma_ch;+			host->dma_ch = -1;+			omap_free_dma(dma_ch);++		}+	}+	else+	{+		if (host->use_dma) {+			omap_stop_dma_chain_transfers(host->chain_id);+			dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->sg_len,+				host->dma_dir);+			omap_free_dma_chain(host->chain_id);+			mmc_omap_dma_done(host, host->data);+			host->chain_id = -1;+		} 	} 	host->data = NULL; #ifdef CONFIG_OMAP_SDIO@@ -696,16 +839,277 @@ static void sdio_non_dma_xfer(struct mmc } #endif +/* PIO only */+static void+mmc_omap_sg_to_buf(struct mmc_omap_host *host)+{+	struct scatterlist *sg;++	sg = host->data->sg + host->sg_idx;+	host->buffer_bytes_left = sg->length;+	host->buffer = page_address(sg->page) + sg->offset;+	if (host->buffer_bytes_left > host->total_bytes_left)+		host->buffer_bytes_left = host->total_bytes_left;+}+++/* PIO only */+static void+mmc_omap_xfer_data(struct mmc_omap_host *host, int write)+{+	int n;++	if (host->buffer_bytes_left == 0) {+		host->sg_idx++;+		BUG_ON(host->sg_idx == host->sg_len);+		mmc_omap_sg_to_buf(host);+	}+	n = 64;+	if (n > host->buffer_bytes_left)+		n = host->buffer_bytes_left;+	host->buffer_bytes_left -= n;+	host->total_bytes_left -= n;+	host->data->bytes_xfered += n;++	if (write) {+		__raw_writesw(host->base + OMAP_HSMMC_DATA, host->buffer, n);+	} else {+		__raw_readsw(host->base + OMAP_HSMMC_DATA, host->buffer, n);+	}+}+++/*+ * Configure the resptype, cmdtype and send the given command to the card+ */+static void+mmc_omap_start_command13(struct mmc_omap_host *host, struct mmc_command *cmd)+{+	int  cmdreg = 0, resptype = 0, cmdtype = 0;+	unsigned long flags;++	mmc_clk_enable_aggressive(host);+	/* Clear status bits and enable interrupts */+	OMAP_HSMMC_WRITE(host->base, STAT, OMAP_HSMMC_STAT_CLEAR);+	resptype = 2;+	cmdreg = (MMC_SEND_STATUS << 24) | (resptype << 16) | (cmdtype << 22);++	OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);+	OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);+	OMAP_HSMMC_WRITE(host->base, ARG, host->rca);+	OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);+	spin_lock_irqsave(&host->dma_lock, flags);+	host->cmd_13 = 1;+	spin_unlock_irqrestore(&host->dma_lock, flags);+}++/*+ * Notify the core about command completion+ */+static void+mmc_omap_err_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)+{+	cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);+	mmc_clk_disable_aggressive(host);+	if(host->cmd_13 == 1)+	{+		if(cmd->resp[0] != 0x900)+			dev_dbg(mmc_dev(host->mmc),+				"%s:CMD response error cmd->resp[0]%x\n",+				mmc_hostname(host->mmc),cmd->resp[0]);+	}+}++++static int+mmc_omap_err_calc(struct mmc_omap_host *host)+{+	unsigned sg_len_remain;+	struct mmc_data *data = host->data;+	unsigned long flags;++	if(unlikely(host == NULL))+	{+		return -1;+	}+	/* Enable DMA */+	host->use_dma = 1;+	spin_lock_irqsave(&host->dma_lock, flags);++	if(host->extra_chain_reqd == 0)+	{+		if(host->data->sg_len <= NO_OF_DMA_CHAINS_USED)+			host->sg_idx = 0;+		else+			host->sg_idx = host->sg_idx-NO_OF_DMA_CHAINS_USED;+	}+	else+	{+		if(host->sg_idx == host->data->sg_len)+			host->sg_idx = host->data->sg_len;+		else+			host->sg_idx = host->sg_idx-NO_OF_DMA_CHAINS_USED;+	}+	if(host->sg_idx == host->data->sg_len)+		sg_len_remain =1;+	else+		sg_len_remain = data->sg_len - host->sg_idx;+	if(sg_len_remain >= NO_OF_DMA_CHAINS_USED)+	{+		host->chains_requested = NO_OF_DMA_CHAINS_USED;+	}+	else+	{+		host->chains_requested = 1;+	}+	if(host->data->sg_len <= NO_OF_DMA_CHAINS_USED)+	{+		host->extra_chain_reqd = 0;+		host->no_of_chain_reqd = 0;+		host->current_cb_cnt = 0;+	}+	else+	{+		host->no_of_chain_reqd = sg_len_remain/NO_OF_DMA_CHAINS_USED;+		host->extra_chain_reqd= sg_len_remain%NO_OF_DMA_CHAINS_USED;+		host->current_cb_cnt = 1;+	}+	spin_unlock_irqrestore(&host->dma_lock, flags);++	return 0;++}++++/*+ * Routine to configure block leangth for MMC/SD/SDIO cards+ * and intiate the transfer.+ */+static int+mmc_omap_err_prepare_data(struct mmc_omap_host *host)+{+	int i;+	unsigned count=0, count1=0;+	struct mmc_data *data = host->data;++	if(unlikely(host == NULL))+	{+		return -1;+	}+	mmc_clk_enable_aggressive(host);	+	if (host->use_dma && host->chain_id != -1) {+		omap_stop_dma_chain_transfers(host->chain_id);+/*		  dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len,+			host->dma_dir);*/+		omap_free_dma_chain(host->chain_id);+		host->chain_id = -1;+	}++	for(i = 0 ;i < host->sg_idx; i++)+	{+		count1 += (sg_dma_len(&data->sg[i])/data->blksz);+	}++	for(i = host->sg_idx ;i < (host->chains_requested+host->sg_idx); i++)+	{+		count += (sg_dma_len(&data->sg[i])/data->blksz);+	}++	OMAP_HSMMC_WRITE(host->base, BLK, (host->data->blksz));+	OMAP_HSMMC_WRITE(host->base, BLK,+					OMAP_HSMMC_READ(host->base,+					BLK) | (count << 16));+	host->mod_addr = host->org_addr;+	if(host->is_high_capacity ==1)+		host->mod_addr += count1;//as card is high capacity+	else+		host->mod_addr += (count1*512);//as card is not high capacity+	host->datadir = (host->data->flags & MMC_DATA_WRITE) ?+			OMAP_MMC_DATADIR_WRITE : OMAP_MMC_DATADIR_READ;+	if (mmc_omap_get_dma_channel(host, data) == 0)+	{+		enum dma_data_direction dma_data_dir;++		if (data->flags & MMC_DATA_WRITE)+			dma_data_dir = DMA_TO_DEVICE;+		else+			dma_data_dir = DMA_FROM_DEVICE;+		host->total_bytes_left = 0;+		mmc_chain_dma(host, host->data);+		host->brs_received = 0;+		host->dma_done = 0;+		/* Enable DMA */+		host->use_dma = 1;+	}+	mmc_clk_disable_aggressive(host);	+	return 0;+}++/*+ * Notify the xfer done on MMC/SD cards to the core+ */+static void+mmc_omap_read_err_done(struct mmc_omap_host *host, struct mmc_data *data)+{+	unsigned long flags;++	spin_lock_irqsave(&host->dma_lock, flags);+	host->flag_err = 1;+	host->cmd_12 = 1;+	spin_unlock_irqrestore(&host->dma_lock, flags);+	mmc_clk_disable_aggressive(host);+	mmc_omap_start_command(host, data->stop);+}+

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -