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

📄 sdio.patch

📁 patches for linux-2.6.
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
diff -Naur -x '.*' -x '*~' -x '*.o' -x '*.ko' -x '*.mod.c' -x '*.cmd' linux26-cvs.BOM/drivers/mmc/au1xmmc.c linux26-cvs.sdio/drivers/mmc/au1xmmc.c--- linux26-cvs.BOM/drivers/mmc/au1xmmc.c	2005-10-20 18:17:10.000000000 +0200+++ linux26-cvs.sdio/drivers/mmc/au1xmmc.c	2005-10-20 18:19:25.000000000 +0200@@ -15,6 +15,9 @@  *     (drivers/mmc/pxa.c) Copyright (C) 2003 Russell King,   *     All Rights Reserved. + *  SDIO support: Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.+ *                by Robert Richter+  * This program is free software; you can redistribute it and/or modify  * it under the terms of the GNU General Public License version 2 as  * published by the Free Software Foundation.@@ -49,6 +52,8 @@ #include <asm/mach-au1x00/au1100_mmc.h> #include <asm/scatterlist.h> +#undef CONFIG_PM+ #ifdef CONFIG_MIPS_PB1200 #include <asm/mach-pb1x00/pb1200.h> #endif@@ -62,6 +67,7 @@ #endif  +#include <linux/mmc/sdiohost.h> #include "au1xmmc.h"  #define DRIVER_NAME "au1xxx-mmc"@@ -75,10 +81,10 @@ /* Set this to enable special debugging macros */ /* #define MMC_DEBUG */ -#ifdef MMC_DEBUG-#define DEBUG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args)+#ifdef CONFIG_MMC_DEBUG+#define DBG(fmt, x...) printk("%s:%4d: " fmt, "AU1XMMC", __LINE__, ##x) #else-#define DEBUG(fmt, idx, args...)+#define DBG(fmt, args...) do { } while (0) #endif  #ifdef CONFIG_PM @@ -224,14 +230,17 @@  	u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); -	switch(cmd->flags) {+	switch(cmd->flags & MMC_RSP_BITS) {+	case MMC_RSP_NONE:+		mmccmd |= SD_CMD_RT_0;+		break; 	case MMC_RSP_R1: #ifdef AU1XMMC_DO_SD 		if (cmd->opcode == 0x03 && host->mmc->mode == MMC_MODE_SD) 			mmccmd |= SD_CMD_RT_6; 		else #endif-		mmccmd |= SD_CMD_RT_1;+			mmccmd |= SD_CMD_RT_1; 		break; 	case MMC_RSP_R1B: 		mmccmd |= SD_CMD_RT_1B;@@ -242,6 +251,15 @@ 	case MMC_RSP_R3: 		mmccmd |= SD_CMD_RT_3; 		break;+	case SDIO_RSP_R4:+		mmccmd |= SD_CMD_RT_4;+		break;+	case SDIO_RSP_R5:+		mmccmd |= SD_CMD_RT_5;+		break;+	default:+		return MMC_ERR_INVALID;+		break; 	}  	switch(cmd->opcode) {@@ -255,13 +273,40 @@ 	case MMC_WRITE_BLOCK: 		mmccmd |= SD_CMD_CT_1; 		break;-	 	case MMC_WRITE_MULTIPLE_BLOCK: 		mmccmd |= SD_CMD_CT_3; 		break;+	case SD_IO_SEND_OP_COND:+	case SD_IO_RW_DIRECT:+	case SD_IO_RW_EXTENDED:+		switch (cmd->flags & SDIO_DAT_MASK) {+		case SDIO_DAT_WR_BLK:+			mmccmd |= SD_CMD_CT_1;+			break;+		case SDIO_DAT_RD_BLK:+			mmccmd |= SD_CMD_CT_2;+			break;+		case SDIO_DAT_WR_MULTI_BLK:+			mmccmd |= SD_CMD_CT_3;+			break;+		case SDIO_DAT_RD_MULTI_BLK:+			mmccmd |= SD_CMD_CT_4;+			break;+		case SDIO_DAT_STOP:+			mmccmd |= SD_CMD_CT_7;+			break;+		case SDIO_DAT_NONE:+		default:+			mmccmd |= SD_CMD_CT_0;+			break;+		}+		break; 	case MMC_STOP_TRANSMISSION: 		mmccmd |= SD_CMD_CT_7; 		break;+	default:+		mmccmd |= SD_CMD_CT_0;+		break; 	} 	 	au_writel(cmd->arg, HOST_CMDARG(host));@@ -275,6 +320,7 @@  	/* Wait for the command to go on the line */ +	/* FIXME: This may end in an infinite loop */ 	while(1) { 		if (!(au_readl(HOST_CMD(host)) & SD_CMD_GO)) 			break;@@ -285,6 +331,7 @@ 	if (wait) { 		u32 status = au_readl(HOST_STATUS(host)); +		/* FIXME: This may end in an infinite loop */ 		while(!(status & SD_STATUS_CR))  			status = au_readl(HOST_STATUS(host)); 		@@ -315,6 +362,7 @@  	/* The transaction is really over when the SD_STATUS_DB bit is clear */ +	/* FIXME: This may end in an infinite loop */ 	while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))  		status = au_readl(HOST_STATUS(host)); @@ -340,7 +388,7 @@ 			u32 chan = DMA_CHANNEL(host);  			chan_tab_t *c = *((chan_tab_t **) chan);-			volatile au1x_dma_chan_t *cp = c->chan_ptr;+			au1x_dma_chan_t *cp = c->chan_ptr; 			data->bytes_xfered = cp->ddma_bytecnt; 		} 		else @@ -452,18 +500,18 @@ 			break;  		if (status & SD_STATUS_RC) {-			DEBUG("RX CRC Error [%d + %d].\n", host->id, +			DBG("#%d: RX CRC Error [%d + %d].\n", host->id,  					host->pio.len, count); 			break; 		}  		if (status & SD_STATUS_RO) {-			DEBUG("RX Overrun [%d + %d]\n", host->id, +			DBG("#%d: RX Overrun [%d + %d]\n", host->id,  					host->pio.len, count); 			break; 		} 		else if (status & SD_STATUS_RU) {-			DEBUG("RX Underrun [%d + %d]\n", host->id, +			DBG("#%d: RX Underrun [%d + %d]\n", host->id,  					host->pio.len,	count); 			break; 		}@@ -562,6 +610,7 @@  		/* Start the DMA as soon as the buffer gets something in it */ +		/* FIXME: This may end in an infinite loop */ 		if (host->flags & HOST_F_RECV) { 			u32 mask = SD_STATUS_DB | SD_STATUS_NE; @@ -647,12 +696,12 @@ 		if (i == (host->dma.len - 1)) 				flags = DDMA_FLAGS_IE; -    			if (host->flags & HOST_F_XMIT)-      				ret = au1xxx_dbdma_put_source_flags(channel, +			if (host->flags & HOST_F_XMIT)+				ret = au1xxx_dbdma_put_source_flags(channel,  								    (void *) phys_to_virt(sg_addr),  								    len, flags);-    			else-      				ret = au1xxx_dbdma_put_dest_flags(channel, +			else+				ret = au1xxx_dbdma_put_dest_flags(channel,  								  (void *) phys_to_virt(sg_addr), 								  len, flags); @@ -661,10 +710,11 @@  			datalen -= len; 		}-+		 	return MMC_ERR_NONE;   dataerr:+	DBG("Data error\n"); 	dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir);  	return MMC_ERR_TIMEOUT; } @@ -726,7 +776,7 @@ 	au_sync();  	/* Configure interrupts */-	au_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host));+	au_writel(AU1XMMC_INTERRUPTS | SD_CONFIG_SI, HOST_CONFIG(host)); 	au_sync(); } 	@@ -734,7 +784,7 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) { 	struct au1xmmc_host *host = mmc_priv(mmc); -	DEBUG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n",+	DBG("#%d: set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n", 	      host->id, ios->power_mode, ios->clock, ios->vdd,  	      ios->bus_mode); @@ -798,12 +848,17 @@ 		status = au_readl(HOST_STATUS(host));  		if (host->mrq && (status & STATUS_TIMEOUT)) {-			if (status & SD_STATUS_RAT)  +			if (status & SD_STATUS_RAT) {+				DBG("Response access timeout\n"); 				host->mrq->cmd->error = MMC_ERR_TIMEOUT;+			}+			else if (status & SD_STATUS_DT) {+				DBG("Data access timeout\n");+				if (host->mrq->data != NULL)+					host->mrq->data->error =+						MMC_ERR_TIMEOUT;+			} 			-			else if (status & SD_STATUS_DT) -				host->mrq->data->error = MMC_ERR_TIMEOUT;-		 			/* In PIO mode, interrupts might still be enabled */ 			IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH); 			tasklet_schedule(&host->finish_task);@@ -820,8 +875,11 @@ 			    (status & STATUS_DATA_IN)) 				au1xmmc_receive_pio(host); 		}+		else if (status & (SD_STATUS_SI)) {+			sdio_host_irq_handler(host->mmc);+		} 		else if (status & 0x203FBC70) {-			DEBUG("Unhandled status %8.8x\n", host->id, status);+			DBG("#%d: Unhandled status %8.8x\n", host->id, status); 			handled = 0; 		} 		@@ -850,8 +908,8 @@  #ifdef MMC_DEBUG 	if (host->mrq != NULL) {-		u32 status = au_readl(HOST_STATUS(host));-		DEBUG("PENDING - %8.8x\n", host->id, status);+		DBG("#%d: PENDING - %8.8x\n", host->id, +		      au_readl(HOST_STATUS(host))); 	} #endif @@ -911,7 +969,7 @@  	int i, ret = 0; -	/* THe interrupt is shared among all controllers */+	/* The interrupt is shared among all controllers */ 	ret = request_irq(AU1100_SD_IRQ, au1xmmc_irq, SA_INTERRUPT, "MMC", 0);    	if (ret) {@@ -922,6 +980,7 @@ 	disable_irq(AU1100_SD_IRQ);  	for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {+		int err = 0; 		struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), dev); 		struct au1xmmc_host *host = 0; @@ -930,9 +989,17 @@ 			au1xmmc_hosts[i] = 0; 			continue; 		}-+		+		err = sdio_host_alloc(mmc);+		if (err != 0) {+			mmc_free_host(mmc);+			printk(DRIVER_NAME " ERROR:  Failed to initialize SDIO host %d\n", i);+			au1xmmc_hosts[i] = 0;+			continue;+		}+		 		mmc->ops = &au1xmmc_ops;-   +		 		mmc->f_min =   450000; 		mmc->f_max = 24000000; @@ -975,6 +1042,10 @@ 		if (dma != 0) 			au1xmmc_init_dma(host); +		/* Since au1xmmc_reset_controller() enables the SDIO +		   interrupt, it has to be called after sdio_host_alloc() that +		   prepares the SDIO ISR.+		*/ 		au1xmmc_reset_controller(host);  		mmc_add_host(mmc);@@ -992,31 +1063,33 @@ }      static int au1xmmc_remove(struct device *dev) {-  	int i;-+	 	disable_irq(AU1100_SD_IRQ);-  +	 	for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { 		struct au1xmmc_host *host = au1xmmc_hosts[i]; 		if (!host) continue;--		tasklet_kill(&host->data_task);-		tasklet_kill(&host->finish_task);-+		 		del_timer_sync(&host->timer);+		mmc_remove_host(host->mmc);+		 		au1xmmc_set_power(host, 0);+		au_writel(0x0, HOST_ENABLE(host));+		au_sync(); 		-		mmc_remove_host(host->mmc);-     		au1xxx_dbdma_chan_free(host->tx_chan); 		au1xxx_dbdma_chan_free(host->rx_chan);-   -		au_writel(0x0, HOST_ENABLE(host));-		au_sync();	-	} -+		+		tasklet_kill(&host->finish_task);+		tasklet_kill(&host->data_task);+		+		sdio_host_free(host->mmc);+		mmc_free_host(host->mmc);+	}+	 	free_irq(AU1100_SD_IRQ, 0);+	 	return 0; } @@ -1036,7 +1109,7 @@ 	int retval = -1; 	unsigned int addr = 0; -	DEBUG("Entering au1xmmc_pm_callback to service request type: %d\n", request);+	DBG("Entering au1xmmc_pm_callback to service request type: %d\n", request);       	 struct au1xmmc_host *host=au1xmmc_hosts[0]; 	diff -Naur -x '.*' -x '*~' -x '*.o' -x '*.ko' -x '*.mod.c' -x '*.cmd' linux26-cvs.BOM/drivers/mmc/Kconfig linux26-cvs.sdio/drivers/mmc/Kconfig--- linux26-cvs.BOM/drivers/mmc/Kconfig	2005-10-20 18:17:10.000000000 +0200+++ linux26-cvs.sdio/drivers/mmc/Kconfig	2005-10-18 13:00:40.000000000 +0200@@ -2,7 +2,7 @@ # MMC subsystem configuration # -menu "MMC/SD Card support"+menu "MMC/SD/SDIO Card support"  config MMC 	tristate "MMC support"@@ -19,6 +19,14 @@ 	  This is an option for use by developers; most people should 	  say N here.  This enables MMC core and driver debugging. +config SDIO_EXT+	bool "Use external SDIO functions"+	depends on MMC != n+	help+	  This option enables the usage of external SDIO function. This is +	  useful if there are SDIO features of builtin functions that are not+	  fully supported.+ config MMC_BLOCK 	tristate "MMC block device driver" 	depends on MMC@@ -81,7 +89,7 @@ 	  in the iPAQ hx4700 and others.  config MMC_AU1X-	tristate "Alchemy AU1XX0 MMC Card Interface support"+	tristate "Alchemy AU1XX0 MMC/SD/SDIO Host Controller support" 	depends on SOC_AU1X00 && MMC 	help 	  This selects the AMD Alchemy(R) Multimedia card interface.diff -Naur -x '.*' -x '*~' -x '*.o' -x '*.ko' -x '*.mod.c' -x '*.cmd' linux26-cvs.BOM/drivers/mmc/Makefile linux26-cvs.sdio/drivers/mmc/Makefile--- linux26-cvs.BOM/drivers/mmc/Makefile	2005-10-20 18:17:10.000000000 +0200+++ linux26-cvs.sdio/drivers/mmc/Makefile	2005-10-18 17:42:46.000000000 +0200@@ -5,7 +5,7 @@ # # Core #-obj-$(CONFIG_MMC)		+= mmc_core.o+obj-$(CONFIG_MMC)		+= mmc_core.o sdio_core.o  # # Media drivers@@ -24,3 +24,4 @@ obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o  mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o+sdio_core-y := sdio.o sdiobus.odiff -Naur -x '.*' -x '*~' -x '*.o' -x '*.ko' -x '*.mod.c' -x '*.cmd' linux26-cvs.BOM/drivers/mmc/mmc.c linux26-cvs.sdio/drivers/mmc/mmc.c--- linux26-cvs.BOM/drivers/mmc/mmc.c	2005-10-20 18:17:10.000000000 +0200+++ linux26-cvs.sdio/drivers/mmc/mmc.c	2005-10-20 18:01:40.000000000 +0200@@ -5,6 +5,9 @@  *  *  SD support (c) 2004 Ian Molton.  *+ *  SDIO support: Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.+ *                by Robert Richter+ *  * This program is free software; you can redistribute it and/or modify  * it under the terms of the GNU General Public License version 2 as  * published by the Free Software Foundation.@@ -27,16 +30,15 @@ #include <linux/mmc/host.h> #include <linux/mmc/protocol.h> +#include "sdio.h" #include "mmc.h"  #ifdef CONFIG_MMC_DEBUG-#define DBG(x...)	printk(KERN_DEBUG x)+#define DBG(fmt, x...)	printk("%s:%4d: " fmt, "MMC", __LINE__, ##x) #else #define DBG(x...)	do { } while (0) #endif -#define CMD_RETRIES	3- /*  * OCR Bit positions to 10s of Vdd mV.  */@@ -65,6 +67,72 @@ 	35,	40,	45,	50,	55,	60,	70,	80, }; +/* SDIO functions */++static inline+struct sd_card* sdio_card_alloc(struct mmc_host* host) {+	struct sd_card* card = NULL;+	+	if  (host->sdio_host != NULL)+		card = host->sdio_host->ops->sdio_card_alloc();+	+	return card;+}++static inline+void sdio_card_free(struct mmc_host* host, struct sd_card * card) {+	if  (host->sdio_host != NULL)+		host->sdio_host->ops->sdio_card_free(card);+}++static inline +int sdio_card_register (struct mmc_host* host, struct sd_card *card) {+	int err = MMC_ERR_NONE;+	+	if  (host->sdio_host != NULL)+		err = host->sdio_host->ops->sdio_card_register(card);

⌨️ 快捷键说明

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