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

📄 x

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻
📖 第 1 页 / 共 3 页
字号:
++/*+ * Notify the xfer done on MMC/SD cards to the core+ */+static void+mmc_omap_err_done(struct mmc_omap_host *host, struct mmc_data *data)+{+	host->data = NULL;+	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;+	}++	host->datadir = OMAP_MMC_DATADIR_NONE;+	host->sg_dma_len = 0;++	mmc_clk_disable_aggressive(host);++	if (!data->stop) {+		host->mrq = NULL;+		mmc_request_done(host->mmc, data->mrq);+		return;+	}+	mmc_omap_start_command(host, data->stop);+}+++ /*  * The MMC controller IRQ handler  */ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) { 	struct mmc_omap_host *host = (struct mmc_omap_host *)dev_id;-	int end_command, end_transfer, status;+	int end_command, end_transfer, status, read_crc =0;+	unsigned long flags; 	typeof(jiffies) timeout; -	if (host->cmd == NULL && host->data == NULL) {+	if (unlikely(host == NULL))+	{+		return IRQ_HANDLED;+	}++	if(unlikely(host->cmd == NULL && host->data == NULL)) { 		status = OMAP_HSMMC_READ(host->base, STAT); 		if (status != 0) { 			OMAP_HSMMC_WRITE(host->base, STAT, status);@@ -732,6 +1136,17 @@ static irqreturn_t mmc_omap_irq(int irq, 	status = OMAP_HSMMC_READ(host->base, STAT); 	dev_dbg(mmc_dev(host->mmc), "Status in IRQ %x\n", status); +	if(unlikely(host->use_dma == 0))+	{+		if (host->total_bytes_left != 0) {+			if ((status & OMAP_MMC_STAT_BRR) ||+				(status & TC))+				mmc_omap_xfer_data(host, 0);+			if (status & OMAP_MMC_STAT_BWR)+				mmc_omap_xfer_data(host, 1);+		}+	}+ 	if (status & (OMAP_HSMMC_ERR)) { 		if (status & (OMAP_HSMMC_CMD_TIMEOUT) || 			status & (OMAP_HSMMC_CMD_CRC)) {@@ -741,6 +1156,7 @@ static irqreturn_t mmc_omap_irq(int irq, 					 * Timeouts are normal in case of 					 * MMC_SEND_STATUS 					 */+ 					if (host->cmd->opcode != 						MMC_ALL_SEND_CID) 						dev_dbg(mmc_dev(host->mmc),@@ -770,7 +1186,31 @@ static irqreturn_t mmc_omap_irq(int irq, 						mmc_hostname(host->mmc)); 					mmc_dma_cleanup(host); 				} else {-					host->data->error |= MMC_ERR_BADCRC;+					if(host->data->flags & MMC_DATA_READ)+					{+						read_crc = 1;+						if(host->flag_err == 1)+						{+							dev_dbg(mmc_dev(host->mmc),+								"%s:Data CRC for the second time\n",+								mmc_hostname(host->mmc));+							spin_lock_irqsave(&host->dma_lock, flags);+							host->crc_retry++;+							host->flag_err = 0;+							spin_unlock_irqrestore(&host->dma_lock, flags);+							if(host->crc_retry == MAX_CRC_RETRY)+							{+								spin_lock_irqsave(&host->dma_lock, flags);+								host->mod_addr = host->org_addr = 0;+								host->flag_err = host->cmd_12 = host->cmd_13 = 0;+								spin_unlock_irqrestore(&host->dma_lock, flags);+								host->data->error |= MMC_ERR_BADCRC;+								mmc_omap_err_done(host, host->data);+							}+						}+				   }+					else+						host->data->error |= MMC_ERR_BADCRC; 					dev_dbg(mmc_dev(host->mmc), 							"%s: Data CRC error," 							" bytes left %d\n",@@ -802,15 +1242,15 @@ static irqreturn_t mmc_omap_irq(int irq, 			dev_dbg(mmc_dev(host->mmc), 				"MMC%d: SDIO CARD interrupt status %x\n", 				host->id, status);-			OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK & +			OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK & 				(~OMAP_HSMMC_CARD_INT)); 			host->sdio_card_intr = 0;-			/*	+			/* 			 * SDIO Card interrupt notifier code should go here, 			 * it should clear the source of interrupt and then 			 * call again the interrupt enable API. 			 */-			return IRQ_HANDLED;	+			return IRQ_HANDLED; 		} 	} #endif@@ -820,20 +1260,59 @@ static irqreturn_t mmc_omap_irq(int irq, #endif /* ifdef CONFIG_OMAP_SDIO */  	OMAP_HSMMC_WRITE(host->base, STAT, status);+	if(host->flag_err == 1)+	{+		if(host->cmd_12 == 1)+		{+			if (status & CC) {+				mmc_omap_err_cmd_done(host, host->cmd);+				spin_lock_irqsave(&host->dma_lock, flags);+				host->cmd_12 =0;+				spin_unlock_irqrestore(&host->dma_lock, flags);+				mmc_omap_start_command13(host, host->cmd);+				return IRQ_HANDLED;+			}+		}+		if(host->cmd_13 == 1)+		{+			if (status & CC) {+				mmc_omap_err_cmd_done(host, host->cmd);+				spin_lock_irqsave(&host->dma_lock, flags);+				host->cmd_13 =0;+				spin_unlock_irqrestore(&host->dma_lock, flags);+				mmc_omap_err_prepare_data(host);+				omap_start_dma_chain_transfers(host->chain_id);+				mmc_omap_start_command18(host, host->cmd);+				return IRQ_HANDLED;+			}+		}+		return IRQ_HANDLED;+	}  	if (end_command || (status & CC)) { 		mmc_omap_cmd_done(host, host->cmd); 	} -	if (end_transfer || (status & TC)) {-		if (host->mmc->mode == MMC_MODE_MMC-			|| host->mmc->mode == MMC_MODE_SD)-			mmc_omap_xfer_done(host, host->data);+	if (host->mmc->mode == MMC_MODE_MMC+		|| host->mmc->mode == MMC_MODE_SD){+		if (end_transfer){+			if(read_crc)+			{+				mmc_omap_err_calc(host);+				mmc_omap_read_err_done(host, host->data);+			}+			else+				mmc_omap_err_done(host, host->data);+			}+		else if (status & TC)+			mmc_omap_end_of_data(host, host->data);+	} #ifdef CONFIG_OMAP_SDIO-		else if (host->mmc->mode == MMC_MODE_SDIO)+	if(host->mmc->mode == MMC_MODE_SDIO){+		if (end_transfer || (status & TC)) 			sdio_omap_xfer_done(host, host->sdiodata);-#endif	/* ifdef CONFIG_OMAP_SDIO */ 	}+#endif	/* ifdef CONFIG_OMAP_SDIO */  	return IRQ_HANDLED; }@@ -843,7 +1322,7 @@ static irqreturn_t mmc_omap_irq(int irq,  * Function for polling mode read write for SDIO cards  */ static void mmc_omap_polling_command(struct mmc_omap_host *host,-				     struct mmc_command *cmd, u32 cmdreg)+					 struct mmc_command *cmd, u32 cmdreg) { 	int i, readCnt, bytec, status = 0; 	typeof(jiffies) timeout;@@ -927,12 +1406,18 @@ static int mmc_omap_power(struct mmc_oma 	int ret = 0;  	if (on){-		if (machine_is_omap_2430sdp() || machine_is_omap_3430sdp()-		    || machine_is_omap_3430labrador() || machine_is_omap3_beagle() )+		if (machine_is_omap_2430sdp() ||+					machine_is_omap_3430sdp() ||+					machine_is_omap_3430labrador() ||+					machine_is_omap3evm())+ 			ret = enable_mmc_power(host->id); 	} else {-		if (machine_is_omap_2430sdp() || machine_is_omap_3430sdp()-		    || machine_is_omap_3430labrador() || machine_is_omap3_beagle() )+		if (machine_is_omap_2430sdp() ||+					machine_is_omap_3430sdp() ||+					machine_is_omap_3430labrador() ||+					machine_is_omap3evm())+ 			ret = disable_mmc_power(host->id); 	} @@ -957,8 +1442,11 @@ static int omap_mmc_switch_opcond(struct 	if (ret != 0) 		dev_dbg(mmc_dev(host->mmc),"Unable to disable power to MMC1\n"); -	if (machine_is_omap_2430sdp() || machine_is_omap_3430sdp()-	    || machine_is_omap_3430labrador() || machine_is_omap3_beagle() ) {+		if (machine_is_omap_2430sdp() ||+					machine_is_omap_3430sdp() ||+					machine_is_omap_3430labrador() ||+					machine_is_omap3evm()) {+ 		if (switch_power_mode(power_mode)) 			dev_dbg(mmc_dev(host->mmc), "Unable to switch operating" 				"voltage to the card\n");@@ -1024,10 +1512,22 @@ static void mmc_omap_detect(struct work_ static irqreturn_t mmc_omap_irq_cd(int irq, void *dev_id) { 	struct mmc_omap_host *host = (struct mmc_omap_host *)dev_id;+	unsigned long flags; -	if (machine_is_omap_2430sdp() || machine_is_omap_3430sdp()-	    || machine_is_omap_3430labrador() || machine_is_omap3_beagle() )+	if (machine_is_omap_2430sdp() ||+			machine_is_omap_3430sdp() ||+			machine_is_omap_3430labrador() ||+			machine_is_omap3evm())+	{+		spin_lock_irqsave(&host->dma_lock, flags);+		host->card_detected = 1;+		host->mmc->mode = MMC_CARD_NONE;+		host->rca = host->mod_addr = host->org_addr = 0;+		host->is_high_capacity = 0;+		host->flag_err = host->cmd_12 = host->cmd_13 = 0;+		spin_unlock_irqrestore(&host->dma_lock, flags); 		schedule_work(&host->mmc_carddetect_work);+	} 	else 		dev_dbg(mmc_dev(host->mmc), "Place to implement MMC hotplug" 			"implementation based on what the other"@@ -1038,52 +1538,158 @@ static irqreturn_t mmc_omap_irq_cd(int i  /*  * DMA call back function+ lch is chain id in case of chaining  */ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) { 	struct mmc_omap_host *host = (struct mmc_omap_host *)data;+	int chainid = host->chain_id; 	int dma_ch;+	unsigned long flags; -	/*-	 * Only report the error for the time being, until the error handling-	 * for these type of errors is supported from the core-	 */-	if (ch_status & (1 << 11))-		dev_dbg(mmc_dev(host->mmc), " %s :MISALIGNED_ADRS_ERR\n",-			mmc_hostname(host->mmc));+	if(host->flag_err)+	{+		spin_lock_irqsave(&host->dma_lock, flags);+		host->crc_retry =0;+		spin_unlock_irqrestore(&host->dma_lock, flags);+		if(host->no_of_chain_reqd > host->current_cb_cnt)+		{+			spin_lock_irqsave(&host->dma_lock, flags);+			host->current_cb_cnt++;+			spin_unlock_irqrestore(&host->dma_lock, flags);+			mmc_omap_read_err_done(host, host->data);+		}+		else if(host->no_of_chain_reqd == host->current_cb_cnt)+		{+			if(host->extra_chain_reqd == 0)+			{+				/*cleanup and go away*/+				spin_lock_irqsave(&host->dma_lock, flags);+				host->flag_err = 0;+				spin_unlock_irqrestore(&host->dma_lock, flags);+				omap_stop_dma_chain_transfers(chainid);+				omap_free_dma_chain(chainid);+				mmc_omap_dma_done(host, host->data);+				host->chain_id = -1; -	if (host->dma_ch < 0) {-		dev_dbg(mmc_dev(host->mmc), "%s:"-			"DMA callback while DMA not enabled?\n",-			mmc_hostname(host->mmc));+			}+			else+			{+				/*do the last transfer*/+				spin_lock_irqsave(&host->dma_lock, flags);+				host->chains_requested = host->extra_chain_reqd;+				host->extra_chain_reqd = 0;+				spin_unlock_irqrestore(&host->dma_lock, flags);+				mmc_omap_read_err_done(host, host->data);+			}+		} 		return; 	}+	if(host->mmc->mode == MMC_MODE_SDIO)+	{+		/*+		 * Only report the error for the time being, until the error handling+		 * for these type of errors is supported from the core+		 */+		if (ch_status & (1 << 11))+			dev_dbg(mmc_dev(host->mmc), " %s :MISALIGNED_ADRS_ERR\n",+				mmc_hostname(host->mmc));++		if (host->dma_ch < 0) {+			dev_dbg(mmc_dev(host->mmc), "%s:"+				"DMA callback while DMA not enabled?\n",+				mmc_hostname(host->mmc));+			return;+		} -	dma_ch = host->dma_ch;-	host->dma_ch = -1;-	omap_free_dma(dma_ch);-	up(&host->sem);+		dma_ch = host->dma_ch;+		host->dma_ch = -1;+		omap_free_dma(dma_ch);+	}+	else+	{+		/* If we are at the last transfer, Shut down the reciever */+		if (omap_dma_chain_status(chainid) == OMAP_DMA_CHAIN_INACTIVE) {+			if(host->no_of_chain_reqd > host->current_cb_cnt)+			{+				mmc_chain_dma(host, host->data);+				omap_dma_set_interrupt_ch(host->chain_id, OMAP_DMA_DROP_IRQ |+								 OMAP2_DMA_MISALIGNED_ERR_IRQ |+								 OMAP2_DMA_TRANS_ERR_IRQ,+								 OMAP_DMA_DROP_IRQ |+								 OMAP_DMA_BLOCK_IRQ |+								 OMAP2_DMA_MISALIGNED_ERR_IRQ |+								 OMAP2_DMA_TRANS_ERR_IRQ);+				omap_start_dma_chain_transfers(host->chain_id);+				spin_lock_irqsave(&host->dma_lock, flags);+				host->current_cb_cnt++;+				spin_unlock_irqrestore(&host->dma_lock, flags);+			}+			else if(host->no_of_chain_reqd == host->current_cb_cnt)+			{+				if(host->extra_chain_reqd == 0)+				{+					omap_stop_dma_chain_transfers(chainid);+					omap_free_dma_chain(chainid);+					mmc_omap_dma_done(host, host->data);+					host->chain_id = -1;+				}+				else+				{+					omap_stop_dma_chain_transfers(chainid);+					omap_free_dma_chain(chainid);+					host->chain_id = -1;+					spin_lock_irqsave(&host->dma_lock, flags);+					host->chains_requested = host->extra_chain_reqd;+					spin_unlock_irqrestore(&host->dma_lock, flags);+					mmc_omap_get_dma_channel(host, host->data);+					mmc_chain_dma(host, host->data);+					omap_start_dma_chain_transfers(host->chain_id);+					spin_lock_irqsave(&host->dma_lock, flags);+					host->extra_chain_reqd = 0;+					spin_unlock_irqrestore(&host->dma_lock, flags);+				}+			}+			else+			{+				dev_dbg(mmc_dev(host->mmc), "%s:"+					"DMA callback ERROR\n",+					mmc_hostname(host->mmc));+			}+		}+		else+		{+			dev_dbg(mmc_dev(host->mmc), "%s:"+				"DMA callback Channel active?\n",+				mmc_hostname(host->mmc));+		}+	} }+++#ifdef CONFIG_OMAP_SDIO+#ifndef CONFIG_OMAP_SDIO_NON_DMA_MODE+ /*  * Configure dma src and destination parameters  */ static int mmc_omap_config_dma_param(int sync_dir, struct mmc_omap_host *host,-				     struct mmc_data *data)+					 struct mmc_data *data) { 	if (sync_dir == OMAP_DMA_DST_SYNC) { 		omap_set_dma_dest_params(host->dma_ch, 					0,	// dest_port required only for OMAP1 						OMAP_DMA_AMODE_CONSTANT,-	       		  (dma_addr_t) (host-> mapbase + OMAP_HSMMC_DATA),0, 0);+				  (dma_addr_t) (host-> mapbase + OMAP_HSMMC_DATA),0, 0); 		omap_set_dma_src_params(host->dma_ch, 					0,	// src_port required only for OMAP1 					OMAP_DMA_AMODE_POST_INC,-			    sg_dma_address(&data-> sg[0]), 0, 0);+				sg_dma_address(&data-> sg[0]), 0, 0); 	} else { 		omap_set_dma_src_params(host->dma_ch, 					0,	// src_port required only for OMAP1 				OMAP_DMA_AMODE_CONSTANT,-		       	(dma_addr_t) (host->mapbase +OMAP_HSMMC_DATA),0, 0);+				(dma_addr_t) (host->mapbase +OMAP_HSMMC_DATA),0, 0); 		omap_set_dma_dest_params(host->dma_ch, 					0,	// dest_port required only for OMAP1 				OMAP_DMA_AMODE_POST_INC,@@ -1092,14 +1698,12 @@ static int mmc_omap_config_dma_param(int 	return 0; } -#ifdef CONFIG_OMAP_SDIO-#ifndef CONFIG_OMAP_SDIO_NON_DMA_MODE /*  * Routine to configure and start dma for SDIO card  */ static int sdio_omap_start_dma_transfer(struct mmc_omap_host *host,-			     struct mmc_request *req)+				 struct mmc_request *req) { 	int sync_dev, sync_dir, dma_ch, ret, readCnt, bytecount; 	int nob = 1, func = 0;@@ -1196,36 +1800,42 @@ sdio_omap_start_dma_transfer(struct mmc_ #endif #endif	/* ifdef CONFIG_OMAP_SDIO */ -/*- * Rotine to configure and start DMA for the MMC card- */-static int-mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)+static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data) {-	int sync_dev, sync_dir, dma_ch, ret;-	struct mmc_data *data = req->data;+	int ret = 0;+	int dma_chid;+	u16 frame;+	u32 count;+	struct scatterlist *sg = &data->sg[host->sg_idx];+	int sync_dev = 0;++	frame = data->blksz;/*blk size*/+	count = sg_dma_len(sg)/frame;/*No of blocks*/  	/* 	 * If for some reason the DMA transfer is still active, 	 * we wait for timeout period and free the dma 	 */-	if (host->dma_ch != -1) {-		set_current_state(TASK_INTERRUPTIBLE);-		schedule_timeout(100);-		if (down_trylock(&host->sem)) {-			dma_ch = host->dma_ch;-			host->dma_ch = -1;-			omap_free_dma(dma_ch);-			up(&host->sem);-			return 1;-		}-	} else {-		if (down_trylock(&host->sem)) {-			dev_dbg(mmc_dev(host->mmc),-				"Semaphore was not initialized \n");-			BUG();-		}-	}+	 if(host->chain_id != -1)+		 dev_dbg(mmc_dev(host->mmc),+			 "%s: chain is not free\n",+			 mmc_hostname(host->mmc));++	/*Common params*/+	//host->params.burst_mode =+	host->params.data_type = OMAP_DMA_DATA_TYPE_S32;+	host->params.dst_ei = 0;+	host->params.dst_fi = 0;+	host->params.dst_port = 0;+	host->params.elem_count = (data->blksz / 4);

⌨️ 快捷键说明

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