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

📄 atheros_2_0_hcd.patch

📁 openmoko 使用的sdio wifi驱动源码
💻 PATCH
📖 第 1 页 / 共 4 页
字号:
++	if (request_irq(context->io_irq, s3c24xx_hcd_irq, 0, context->description, context)) {+		DBG_PRINT(SDDBG_ERROR, ("failed to request mci interrupt.\n"));+		status = -ENOENT;+		goto out_unmap_mem_region;+	}+++	/* DMA */+	context->io_buffer_size = 4 * 4096;+	context->io_buffer = dma_alloc_writecombine(&context->pdev->dev,+						    context->io_buffer_size,+						    &context->io_buffer_dma,+						    GFP_KERNEL | GFP_DMA);++	if (context->io_buffer == NULL) {+		DBG_PRINT(SDDBG_ERROR, ("failed to allocate DMA buffer\n"));+		status = -ENOMEM;+		goto out_free_irq;++	}++	if (s3c2410_dma_request(context->dma_channel, &s3c24xx_hcd_dma_client, NULL)) {+		DBG_PRINT(SDDBG_ERROR, ("unable to get DMA channel.\n"));+		status = -ENOENT;+		goto out_free_dma;+	}+++	/* Set multiplexing */+	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);++	con = readl(context->base + S3C2410_SDICON);+	con |= S3C2410_SDICON_SDIOIRQ;+	writel(con, context->base + S3C2410_SDICON);++	datacon = readl(context->base + S3C2410_SDIDCON);+	datacon |= S3C2410_SDIDCON_WIDEBUS;+	writel(datacon, context->base + S3C2410_SDIDCON);++	printk("S3c24xx SDIO: IRQ:%d Detect IRQ:%d DMA channel:%d base@0x%p PCLK@%ld kHz\n",+	       context->io_irq, context->cd_irq, context->dma_channel, context->base,+	       context->device.max_clock_rate/1000);++	return SDIOErrorToOSError(status);++ out_free_dma:+	dma_free_writecombine(&context->pdev->dev,context->io_buffer_size,+			      context->io_buffer, context->io_buffer_dma);++ out_free_irq:+	free_irq(context->io_irq, context);++ out_unmap_mem_region:+	iounmap(context->base);++ out_free_mem_region:+	release_mem_region(context->mem->start, RESSIZE(context->mem));++ out_disable_clock:+	clk_disable(context->device.clock);++	return SDIOErrorToOSError(status);+}++static void s3c24xx_hcd_hw_cleanup(struct s3c24xx_hcd_context * context)+{+	clk_disable(context->device.clock);+	free_irq(context->io_irq, context);+	iounmap(context->base);+	release_mem_region(context->mem->start, RESSIZE(context->mem));+	dma_free_writecombine(&context->pdev->dev,context->io_buffer_size,+			      context->io_buffer, context->io_buffer_dma);+}++static int s3c24xx_hcd_pnp_probe(struct pnp_dev *pBusDevice, const struct pnp_device_id *pId)+{+	SDIO_STATUS status = SDIO_STATUS_SUCCESS;++	status = s3c24xx_hcd_hw_init(&hcd_context);+	if (SDIO_IS_ERROR(status)) {+		DBG_PRINT(SDDBG_ERROR, ("HW Init failed\n"));+		return SDIOErrorToOSError(status);+	}++	status = SDIO_RegisterHostController(&hcd_context.hcd);+	if (SDIO_IS_ERROR(status)) {+		DBG_PRINT(SDDBG_ERROR, ("Host registration failed\n"));+		s3c24xx_hcd_hw_cleanup(&hcd_context);+		return SDIOErrorToOSError(status);+	}++	/* Our card is built-in, we force the attachement event */+	SDIO_HandleHcdEvent(&hcd_context.hcd, EVENT_HCD_ATTACH);++	return 0;+}++static void s3c24xx_hcd_pnp_remove(struct pnp_dev *pBusDevice)+{+}++/* the driver context data */+struct s3c24xx_hcd_context hcd_context = {+	.description  = DESCRIPTION,+	.hcd.pName = "sdio_s3c24xx",+	.hcd.Version = CT_SDIO_STACK_VERSION_CODE,+	.hcd.pModule = THIS_MODULE,+	/* builtin card, 4 bits bus */+	.hcd.Attributes = SDHCD_ATTRIB_BUS_4BIT | SDHCD_ATTRIB_BUS_1BIT | SDHCD_ATTRIB_MULTI_BLK_IRQ,+	.hcd.SlotNumber = 0,+	.hcd.MaxSlotCurrent = 500, /* 1/2 amp */+	.hcd.SlotVoltageCaps = SLOT_POWER_3_3V, /* 3.3V */+	.hcd.SlotVoltagePreferred = SLOT_POWER_3_3V, /* 3.3V */+	.hcd.MaxClockRate = 25000000,+	.hcd.MaxBytesPerBlock = 0xfff, /* 0 - 4095 */+	.hcd.MaxBlocksPerTrans = 0xfff, /* 0 - 4095 */+	.hcd.pContext = &hcd_context,+	.hcd.pRequest = s3c24xx_hcd_request,+	.hcd.pConfigure = s3c24xx_hcd_config,+	.device.pnp_device.name = "sdio_s3c24xx_hcd",+	.device.pnp_driver.name = "sdio_s3c24xx_hcd",+	.device.pnp_driver.probe  = s3c24xx_hcd_pnp_probe,+	.device.pnp_driver.remove = s3c24xx_hcd_pnp_remove,+};++static int s3c24xx_hcd_probe(struct platform_device * pdev)+{+	SDIO_STATUS status = SDIO_STATUS_SUCCESS;+	struct resource *r = NULL;++	printk("S3c2440 SDIO Host controller\n");++	hcd_context.pdev = pdev;++	hcd_context.mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);+	if (hcd_context.mem == NULL) {+		DBG_PRINT(SDDBG_ERROR, ("No memory region\n"));+		status = SDIO_STATUS_NO_RESOURCES;+		goto out;+	}++	hcd_context.io_irq = platform_get_irq(pdev, 0);+	if (hcd_context.io_irq == 0) {+		DBG_PRINT(SDDBG_ERROR, ("No IRQ\n"));+		status = SDIO_STATUS_NO_RESOURCES;+		goto out;+	}++	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);+	if (r == NULL) {+		DBG_PRINT(SDDBG_ERROR, ("No DMA channel\n"));+		status = SDIO_STATUS_NO_RESOURCES;+		goto out;+	}+	hcd_context.dma_channel = r->start;+	hcd_context.dma_en = 0;++	hcd_context.int_sdio = 0;++	spin_lock_init(&hcd_context.lock);++	init_completion(&hcd_context.dma_complete);+	init_completion(&hcd_context.xfer_complete);++	INIT_WORK(&hcd_context.io_work, s3c24xx_hcd_io_work);+	INIT_WORK(&hcd_context.irq_work, s3c24xx_hcd_irq_work);++	mdelay(100);++	status = SDIO_BusAddOSDevice(&hcd_context.device.dma,+				     &hcd_context.device.pnp_driver,+				     &hcd_context.device.pnp_device);++ out:++	return SDIOErrorToOSError(status);+}++/*+ * module cleanup+ */+static int s3c24xx_hcd_remove(struct platform_device * pdev) {+	printk("S3C2440 SDIO host controller unloaded\n");+	SDIO_BusRemoveOSDevice(&hcd_context.device.pnp_driver, &hcd_context.device.pnp_device);++	return 0;+}++static struct platform_driver s3c24xx_hcd_sdio =+{+	.driver.name	= "s3c24xx-sdio",+	.probe		= s3c24xx_hcd_probe,+	.remove		= s3c24xx_hcd_remove,+};++#ifdef CONFIG_DEBUG_FS+static struct dentry *debugfs_dir;++static int s3c24xx_hcd_debugfs_show(struct seq_file *s, void *data)+{+	PSDREQUEST req;+	u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer, bsize;+	u32 datcon, datcnt, datsta, fsta, imask;+	struct s3c24xx_hcd_context * context = &hcd_context;+++	con 	= readl(context->base + S3C2410_SDICON);+	pre 	= readl(context->base + S3C2410_SDIPRE);+	cmdarg 	= readl(context->base + S3C2410_SDICMDARG);+	cmdcon 	= readl(context->base + S3C2410_SDICMDCON);+	cmdsta 	= readl(context->base + S3C2410_SDICMDSTAT);+	r0 	= readl(context->base + S3C2410_SDIRSP0);+	r1 	= readl(context->base + S3C2410_SDIRSP1);+	r2 	= readl(context->base + S3C2410_SDIRSP2);+	r3 	= readl(context->base + S3C2410_SDIRSP3);+	timer 	= readl(context->base + S3C2410_SDITIMER);+	bsize 	= readl(context->base + S3C2410_SDIBSIZE);+	datcon 	= readl(context->base + S3C2410_SDIDCON);+	datcnt 	= readl(context->base + S3C2410_SDIDCNT);+	datsta 	= readl(context->base + S3C2410_SDIDSTA);+	fsta 	= readl(context->base + S3C2410_SDIFSTA);+	imask   = readl(context->base + S3C2440_SDIIMSK);++	seq_printf(s, "SDICON:    0x%08x\n", con);+	seq_printf(s, "SDIPRE:    0x%08x\n", pre);+	seq_printf(s, "SDICmdArg: 0x%08x\n", cmdarg);+	seq_printf(s, "SDICmdCon: 0x%08x\n", cmdcon);+	seq_printf(s, "SDICmdSta: 0x%08x\n", cmdsta);+	seq_printf(s, "SDIRSP0:   0x%08x\n", r0);+	seq_printf(s, "SDIRSP1:   0x%08x\n", r1);+	seq_printf(s, "SDIRSP2:   0x%08x\n", r2);+	seq_printf(s, "SDIRSP3:   0x%08x\n", r3);+	seq_printf(s, "SDIDTimer: 0x%08x\n", timer);+	seq_printf(s, "SDIBSize:  0x%08x\n", bsize);+	seq_printf(s, "SDIDatCon: 0x%08x\n", datcon);+	seq_printf(s, "SDIDatCnt: 0x%08x\n", datcnt);+	seq_printf(s, "SDIDatSta: 0x%08x\n", datsta);+	seq_printf(s, "SDIFSta:   0x%08x\n", fsta);+	seq_printf(s, "SDIIntMsk: 0x%08x\n", imask);+	seq_printf(s, "\n");++	seq_printf(s, "Current REQ: \n");+	req = GET_CURRENT_REQUEST(&context->hcd);+	if (req == NULL) {+		seq_printf(s, " No current request\n");+	} else {+		seq_printf(s, " Command: %d\n", req->Command);+		seq_printf(s, " Args: 0x%x\n", req->Argument);+		seq_printf(s, " Flags: 0x%x\n", req->Flags);+		seq_printf(s, " %d blocks x %d bytes\n", req->BlockCount, req->BlockLen);+		seq_printf(s, " %d bytes remaining\n", req->DataRemaining);+	}++	seq_printf(s, "Context: \n");+	seq_printf(s, " INT mask: 0x%x\n", context->int_mask);+	seq_printf(s, " sdio INT: %d\n", context->int_sdio);+	seq_printf(s, " cmdsta: 0x%x\n", context->cmdsta);+	seq_printf(s, " dsta: 0x%x\n", context->dsta);+	seq_printf(s, " fsta: 0x%x\n", context->fsta);++	return 0;+}++static int s3c24xx_hcd_debugfs_open(struct inode *inode,+					struct file *file)+{+	return single_open(file, s3c24xx_hcd_debugfs_show, NULL);+}++static const struct file_operations s3c24xx_hcd_debugfs_fops = {+	.open		= s3c24xx_hcd_debugfs_open,+	.read		= seq_read,+	.llseek		= seq_lseek,+	.release	= single_release,+	.owner		= THIS_MODULE,+};+++static int s3c24xx_debugfs_init(struct s3c24xx_hcd_context * context)+{+	debugfs_dir = debugfs_create_dir("s3c24xx_sdio", NULL);++	debugfs_create_file("registers", 0444, debugfs_dir,+			    (void *)context,+			    &s3c24xx_hcd_debugfs_fops);++	return 0;+}++#else++static int s3c24xx_debugfs_init(struct s3c24xx_hcd_context * context)+{+	return 0;+}++#endif++static int __init s3c24xx_hcd_init(void)+{+	int ret;++	ret = s3c24xx_debugfs_init(&hcd_context);+	if (ret) {+		printk("%s(): debugfs init failed\n", __FUNCTION__);+	}++	platform_driver_register(&s3c24xx_hcd_sdio);++	return 0;+}++static void __exit s3c24xx_hcd_exit(void)+{+	platform_driver_unregister(&s3c24xx_hcd_sdio);+}+++MODULE_LICENSE("GPL");+MODULE_DESCRIPTION(DESCRIPTION);+MODULE_AUTHOR(AUTHOR);++module_init(s3c24xx_hcd_init);+module_exit(s3c24xx_hcd_exit);Index: linux-2.6.24/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h===================================================================--- /dev/null+++ linux-2.6.24/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h@@ -0,0 +1,67 @@+#ifndef __SDIO_S3C24XX_HCD_H___+#define __SDIO_S3C24XX_HCD_H___++#define S3C24XX_HCD_NO_RESPONSE     1+#define S3C24XX_HCD_RESPONSE_SHORT  2+#define S3C24XX_HCD_RESPONSE_LONG   3+#define S3C24XX_HCD_DATA_READ       4+#define S3C24XX_HCD_DATA_WRITE      5++struct s3c24xx_hcd_device {+	OS_PNPDEVICE   pnp_device;     /* the OS device for this HCD */+	OS_PNPDRIVER   pnp_driver;     /* the OS driver for this HCD */+	SDDMA_DESCRIPTION dma;+	struct clk * clock;+	unsigned long max_clock_rate;+	unsigned long actual_clock_rate;+};+++/* driver wide data, this driver only supports one device,+ * so we include the per device data here also */+struct s3c24xx_hcd_context {+	PTEXT			  description;       /* human readable device decsription */+	SDHCD			  hcd;                /* HCD description for bus driver */+	struct s3c24xx_hcd_device device;             /* the single device's info */+	struct platform_device    *pdev;+	struct resource           *mem;+	void __iomem		  *base;+	UINT32                    io_irq;+	UINT32                    cd_irq;+	BOOL			  card_inserted;       /* card inserted flag */+	BOOL			  cmd_processed;       /* command phase was processed */+	UINT32			  fifo_depth;          /* FIFO depth for the bus mode */+	BOOL			  irq_masked;+	UINT32		  	  bus_width;+	UINT32		  	  data_size;           /* Word, half word, or byte */+	UINT32		  	  latest_xfer_size;++	void                      *io_buffer;         /* Kernel address */+	dma_addr_t                io_buffer_dma;      /* Bus address */+	UINT32                    io_buffer_size;+	UINT32                    dma_channel;+	UINT32                    dma_en;+	struct completion         dma_complete;+	struct completion         xfer_complete;++	UINT32		  	  int_mask;+	UINT32		  	  int_sdio;            /* Do we have SDIO interrupt on ? */++	UINT32		  	  complete;++	UINT32		  	  cmdsta;+	UINT32		  	  dsta;+	UINT32		  	  fsta;++	spinlock_t		  lock;++	struct work_struct        io_work;+	struct work_struct        irq_work;+};++SDIO_STATUS s3c24xx_hcd_config(PSDHCD hcd, PSDCONFIG config);+SDIO_STATUS s3c24xx_hcd_request(PSDHCD hcd);++struct s3c24xx_hcd_context hcd_context;++#endif

⌨️ 快捷键说明

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