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

📄 full-h1940-2.6.21.patch

📁 linux2.6.21的h1940patch
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
+		if (0 == (stoptries--)) {+#ifdef CONFIG_MMC_DEBUG+			dbg_dumpregs(host, "DRF");+#endif++			return -EINVAL;+		}+	}++	dcon  = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK;++	if (host->dodma) {+		dcon |= S3C2410_SDIDCON_DMAEN;+	}++	if (host->bus_width == MMC_BUS_WIDTH_4) {+		dcon |= S3C2410_SDIDCON_WIDEBUS;+	}++	if (!(data->flags & MMC_DATA_STREAM)) {+		dcon |= S3C2410_SDIDCON_BLOCKMODE;+	}++	if (data->flags & MMC_DATA_WRITE) {+		dcon |= S3C2410_SDIDCON_TXAFTERRESP;+		dcon |= S3C2410_SDIDCON_XFER_TXSTART;+	}++	if (data->flags & MMC_DATA_READ) {+		dcon |= S3C2410_SDIDCON_RXAFTERCMD;+		dcon |= S3C2410_SDIDCON_XFER_RXSTART;+	}++	if (host->is2440) {+		dcon |= S3C2440_SDIDCON_DS_WORD;+		dcon |= S3C2440_SDIDCON_DATSTART;+	}++	writel(dcon, host->base + S3C2410_SDIDCON);++	/* write BSIZE register */++	writel(data->blksz, host->base + S3C2410_SDIBSIZE);++	/* add to IMASK register */+	imsk =	S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |+		S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;++	enable_imask(host, imsk);++	/* write TIMER register */++	if (host->is2440) {+		writel(0x007FFFFF, host->base + S3C2410_SDITIMER);+	} else {+		writel(0x0000FFFF, host->base + S3C2410_SDITIMER);++		//FIX: set slow clock to prevent timeouts on read+		if (data->flags & MMC_DATA_READ) {+			writel(0xFF, host->base + S3C2410_SDIPRE);+		}+	}++	//debug_dump_registers(host, "Data setup:");++	return 0;+}++static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)+{+	int rw = (data->flags & MMC_DATA_WRITE)?1:0;++	if (rw != ((data->flags & MMC_DATA_READ)?0:1))+		return -EINVAL;++	host->pio_sgptr = 0;+	host->pio_words = 0;+	host->pio_count = 0;+	host->pio_active = rw?XFER_WRITE:XFER_READ;++	if (rw) {+		do_pio_write(host);+		enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);+	} else {+		enable_imask(host, S3C2410_SDIIMSK_RXFIFOHALF+			| S3C2410_SDIIMSK_RXFIFOLAST);+	}++	return 0;+}++static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)+{+	int dma_len, i;++	int rw = (data->flags & MMC_DATA_WRITE)?1:0;++	if (rw != ((data->flags & MMC_DATA_READ)?0:1))+		return -EINVAL;++	s3cmci_dma_setup(host, rw?S3C2410_DMASRC_MEM:S3C2410_DMASRC_HW);+	s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);++	dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,+				(rw)?DMA_TO_DEVICE:DMA_FROM_DEVICE);+++	if (dma_len == 0)+		return -ENOMEM;++	host->dma_complete = 0;+	host->dmatogo = dma_len;++	for (i = 0; i < dma_len; i++) {+		int res;++		dbg(host, dbg_dma, "enqueue %i:%u@%u\n", i,+			sg_dma_address(&data->sg[i]),+			sg_dma_len(&data->sg[i]));++		res = s3c2410_dma_enqueue(host->dma, (void *) host,+				sg_dma_address(&data->sg[i]),+				sg_dma_len(&data->sg[i]));++		if (res) {+			s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);+			return -EBUSY;+		}+ 	}++	s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_START);++	return 0;+}++static void s3cmci_send_request(struct mmc_host *mmc)+{+	struct s3cmci_host *host = mmc_priv(mmc);+	struct mmc_request *mrq = host->mrq;+	struct mmc_command *cmd = host->cmd_is_stop?mrq->stop:mrq->cmd;++	host->ccnt++;+#ifdef CONFIG_MMC_DEBUG+	prepare_dbgmsg(host, cmd, host->cmd_is_stop);+#endif+	//Clear command, data and fifo status registers+	//Fifo clear only necessary on 2440, but doesn't hurt on 2410+	writel(0xFFFFFFFF, host->base + S3C2410_SDICMDSTAT);+	writel(0xFFFFFFFF, host->base + S3C2410_SDIDSTA);+	writel(0xFFFFFFFF, host->base + S3C2410_SDIFSTA);++	if (cmd->data) {+		int res;+		res = s3cmci_setup_data(host, cmd->data);++		host->dcnt++;++		if (res) {+			cmd->error = MMC_ERR_DMA;+			cmd->data->error = MMC_ERR_DMA;++			mmc_request_done(mmc, mrq);+			return;+		}+++		if (host->dodma) {+			res = s3cmci_prepare_dma(host, cmd->data);+		} else {+			res = s3cmci_prepare_pio(host, cmd->data);+		}++		if (res) {+			cmd->error = MMC_ERR_DMA;+			cmd->data->error = MMC_ERR_DMA;++			mmc_request_done(mmc, mrq);+			return;+		}++	}++	// Send command+	s3cmci_send_command(host, cmd);++	// Enable Interrupt+	enable_irq(host->irq);+}++static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)+{+ 	struct s3cmci_host *host = mmc_priv(mmc);++	host->cmd_is_stop = 0;+	host->mrq = mrq;++	s3cmci_send_request(mmc);+}++static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)+{+	struct s3cmci_host *host = mmc_priv(mmc);+	u32 mci_psc, mci_con;++	//Set power+	mci_con = readl(host->base + S3C2410_SDICON);+	switch(ios->power_mode) {+		case MMC_POWER_ON:+		case MMC_POWER_UP:+			s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);+			s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);+			s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);+			s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);+			s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);+			s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);++			if (!host->is2440)+				mci_con|=S3C2410_SDICON_FIFORESET;++			break;++		case MMC_POWER_OFF:+		default:+			s3c2410_gpio_setpin(S3C2410_GPE5, 0);+			s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_OUTP);++			if (host->is2440)+				mci_con|=S3C2440_SDICON_SDRESET;++			break;+	}++	//Set clock+	for (mci_psc=0; mci_psc<255; mci_psc++) {+		host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1));++		if (host->real_rate <= ios->clock)+			break;+	}++	if(mci_psc > 255) mci_psc = 255;+	host->prescaler = mci_psc;++	writel(host->prescaler, host->base + S3C2410_SDIPRE);++	//If requested clock is 0, real_rate will be 0, too+	if (ios->clock == 0)+		host->real_rate = 0;++	//Set CLOCK_ENABLE+	if (ios->clock)+		mci_con |= S3C2410_SDICON_CLOCKTYPE;+	else+		mci_con &=~S3C2410_SDICON_CLOCKTYPE;++	writel(mci_con, host->base + S3C2410_SDICON);++	if ((ios->power_mode==MMC_POWER_ON)+		|| (ios->power_mode==MMC_POWER_UP)) {++		dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n",+			host->real_rate/1000, ios->clock/1000);+	} else {+		dbg(host, dbg_conf, "powered down.\n");+	}++	host->bus_width = ios->bus_width;++}++static void s3cmci_reset(struct s3cmci_host *host)+{+	u32 con = readl(host->base + S3C2410_SDICON);++	con |= S3C2440_SDICON_SDRESET;++	writel(con, host->base + S3C2410_SDICON);+}++static struct mmc_host_ops s3cmci_ops = {+	.request	= s3cmci_request,+	.set_ios	= s3cmci_set_ios,+};++static struct s3c24xx_mmc_platdata s3c2410_mmc_defplat = {+	.gpio_detect	= S3C2410_GPF2,+};++static int s3cmci_probe(struct platform_device *pdev, int is2440)+{+	struct mmc_host 	*mmc;+	struct s3cmci_host 	*host;+	s3c24xx_mmc_pdata_t	*pdata;++	int ret;++	mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);+	if (!mmc) {+		ret = -ENOMEM;+		goto probe_out;+	}++	host = mmc_priv(mmc);+	host->mmc 	= mmc;+	host->pdev	= pdev;++	spin_lock_init(&host->complete_lock);+	tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);+	if (is2440) {+		host->is2440	= 1;+		host->sdiimsk	= S3C2440_SDIIMSK;+		host->sdidata	= S3C2440_SDIDATA;+		host->clk_div	= 1;+	} else {+		host->is2440	= 0;+		host->sdiimsk	= S3C2410_SDIIMSK;+		host->sdidata	= S3C2410_SDIDATA;+		host->clk_div	= 2;+	}+	host->dodma		= 0;+	host->complete_what 	= COMPLETION_NONE;+	host->pio_active 	= XFER_NONE;++	host->dma		= S3CMCI_DMA;++	pdata = pdev->dev.platform_data;+	if (!pdata) {+		pdev->dev.platform_data = &s3c2410_mmc_defplat;+		pdata = &s3c2410_mmc_defplat;+	}++	host->pdata = pdata;+	host->irq_cd = s3c2410_gpio_getirq(pdata->gpio_detect);++	host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);+	if (!host->mem) {+		dev_err(&pdev->dev,+			"failed to get io memory region resouce.\n");++		ret = -ENOENT;+		goto probe_free_host;+	}++	host->mem = request_mem_region(host->mem->start,+		RESSIZE(host->mem), pdev->name);++	if (!host->mem) {+		dev_err(&pdev->dev, "failed to request io memory region.\n");+		ret = -ENOENT;+		goto probe_free_host;+	}++	host->base = ioremap(host->mem->start, RESSIZE(host->mem));+	if (host->base == 0) {+		dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");+		ret = -EINVAL;+		goto probe_free_mem_region;+	}++	host->irq = platform_get_irq(pdev, 0);+	if (host->irq == 0) {+		dev_err(&pdev->dev, "failed to get interrupt resouce.\n");+		ret = -EINVAL;+		goto probe_iounmap;+	}++	if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) {+		dev_err(&pdev->dev, "failed to request mci interrupt.\n");+		ret = -ENOENT;+		goto probe_iounmap;+	}++	disable_irq(host->irq);++	s3c2410_gpio_cfgpin(pdata->gpio_detect, S3C2410_GPIO_IRQ);++	if (request_irq(host->irq_cd, s3cmci_irq_cd, \+		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRIVER_NAME, host)) {+		dev_err(&pdev->dev,+			"failed to request card detect interrupt.\n");++		ret = -ENOENT;+		goto probe_free_irq;+	}++	if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL)) {+		dev_err(&pdev->dev, "unable to get DMA channel.\n");+		ret = -EBUSY;+		goto probe_free_irq_cd;+	}++	host->clk = clk_get(&pdev->dev, "sdi");+	if (IS_ERR(host->clk)) {+		dev_err(&pdev->dev, "failed to find clock source.\n");+		ret = PTR_ERR(host->clk);+		host->clk = NULL;+		goto probe_free_irq_cd;+	}++	if ((ret = clk_enable(host->clk))) {+		dev_err(&pdev->dev, "failed to enable clock source.\n");+		goto clk_free;+	}++	host->clk_rate = clk_get_rate(host->clk);++	mmc->ops 	= &s3cmci_ops;+	mmc->ocr_avail	= MMC_VDD_32_33;+	mmc->caps	= MMC_CAP_4_BIT_DATA;+	mmc->f_min 	= host->clk_rate / (host->clk_div * 256);+	mmc->f_max 	= host->clk_rate / host->clk_div;++	mmc->max_blk_size	= 4096;+	mmc->max_blk_count	= 4096;+	mmc->max_req_size	= mmc->max_blk_size * 512;+	mmc->max_seg_size	= mmc->max_req_size;++	mmc->max_phys_segs	= 128;+	mmc->max_hw_segs	= 128;++	dbg(host, dbg_debug, "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n",+		(host->is2440?"2440":""),+		host->base, host->irq, host->irq_cd, host->dma);++	if ((ret = mmc_add_host(mmc))) {+		dev_err(&pdev->dev, "failed to add mmc host.\n");+		goto free_dmabuf;+	}++	platform_set_drvdata(pdev, mmc);++	dev_info(&pdev->dev,"initialisation done.\n");+	return 0;++ free_dmabuf:+	clk_disable(host->clk);++ clk_free:+	clk_put(host->clk);++ probe_free_irq_cd:+ 	free_irq(host->irq_cd, host);++ probe_free_irq:+ 	free_irq(host->irq, host);++ probe_iounmap:+	iounmap(host->base);++ probe_free_mem_region:+	release_mem_region(host->mem->start, RESSIZE(host->mem));++ probe_free_host:+	mmc_free_host(mmc);+ probe_out:+	return ret;+}++static int s3cmci_remove(struct platform_device *pdev)+{+	struct mmc_host 	*mmc  = platform_get_drvdata(pdev);+	struct s3cmci_host 	*host = mmc_priv(mmc);++	mmc_remove_host(mmc);+	clk_disable(host->clk);+	clk_put(host->clk);+ 	free_irq(host->irq_cd, host);+ 	free_irq(host->irq, host);+	iounmap(host->base);+	release_mem_region(host->mem->start, RESSIZE(host->mem));+	mmc_free_host(mmc);++	return 0;+}++static int s3cmci_probe_2410(struct platform_device *dev)+{+	return s3cmci_probe(dev, 0);+}++static int s3cmci_probe_2412(struct platform_device *dev)+{+	return s3cmci_probe(dev, 1);+}++static int s3cmci_probe_2440(struct platform_device *dev)+{+	return s3cmci_probe(dev, 1);+}++#ifdef CONFIG_PM++static int s3cmci_suspend(struct platform_device *dev, pm_message_t state)+{+	struct mmc_host

⌨️ 快捷键说明

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