示例#1
0
static int __devinit brcmnanddrv_probe(struct platform_device *pdev)
{
	struct brcmnand_platform_data *cfg = pdev->dev.platform_data;
	//struct flash_platform_data *pdata = pdev->dev.platform_data;
	//struct resource *res = pdev->resource;
	//unsigned long size = res->end - res->start + 1;
	int err = 0;

	gPageBuffer = NULL;
	info = kmalloc(sizeof(struct brcmnand_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	memset(info, 0, sizeof(struct brcmnand_info));

#ifndef CONFIG_MTD_BRCMNAND_EDU
	gPageBuffer = kmalloc(sizeof(struct nand_buffers), GFP_KERNEL);
	info->brcmnand.buffers = (struct nand_buffers*) gPageBuffer;
#else
	/* Align on 32B boundary for efficient DMA transfer */
	gPageBuffer = kmalloc(sizeof(struct nand_buffers) + 31, GFP_DMA);
	info->brcmnand.buffers = (struct nand_buffers*) (((unsigned int) gPageBuffer+31) & (~31));
#endif
	if (!info->brcmnand.buffers) {
		kfree(info);
		return -ENOMEM;
	}

	memset(info->brcmnand.buffers, 0, sizeof(struct nand_buffers));

	memset(gNandCS, 0, MAX_NAND_CS);
	gNumNand = 1;
	gNandCS[0] = cfg->chip_select;

	info->brcmnand.numchips = 1; // For now, we only support 1 chip
	info->brcmnand.chip_shift = 0; // Only 1 chip
	//info->brcmnand.regs = pdev->resource[0].start;
	info->brcmnand.priv = &info->mtd;

	//info->brcmnand.mmcontrol = NULL;  // THT: Sync Burst Read TBD.  pdata->mmcontrol;

	info->mtd.name = dev_name(&pdev->dev);
	info->mtd.priv = &info->brcmnand;
	info->mtd.owner = THIS_MODULE;

	/* Enable the following for a flash based bad block table */
	info->brcmnand.options |= NAND_USE_FLASH_BBT;
	

//printk("brcmnand_scan\n");
	if (brcmnand_scan(&info->mtd, gNumNand)) {
		err = -ENXIO;
		goto out_free_info;
	}

	printk("	numchips=%d, size=%llx\n", info->brcmnand.numchips, device_size(&(info->mtd)));

#ifdef CONFIG_MTD_PARTITIONS
	/* allow cmdlineparts to override the default map */
	err = parse_mtd_partitions(&info->mtd, part_probe_types,
		&info->parts, 0);
	if (err > 0) {
		info->nr_parts = err;
	} else {
		info->parts = cfg->nr_parts ? cfg->parts : NULL;
		info->nr_parts = cfg->nr_parts;
	}

	if (info->nr_parts)
		add_mtd_partitions(&info->mtd, info->parts, info->nr_parts);
	else
		add_mtd_device(&info->mtd);
#else
	add_mtd_device(&info->mtd);
#endif

//printk("	dev_set_drvdata\n");	
	dev_set_drvdata(&pdev->dev, info);
//printk("<-- brcmnanddrv_probe\n");

	return 0;


out_free_info:

	if (gPageBuffer)
		kfree(gPageBuffer);
	kfree(info);
	return err;
}
示例#2
0
static int __devinit brcmnanddrv_probe(struct platform_device *pdev)
{
	struct brcmnand_platform_data *cfg = pdev->dev.platform_data;
	static int csi; // Index into dev/nandInfo array
	int cs = cfg->chip_select;	// Chip Select
	//int i;
	int err = 0;
	//static int numCSProcessed = 0;
	//int lastChip;
	struct brcmnand_info* info;
	

//extern int dev_debug, gdebug;



		/* FOr now all devices share the same buffer */
	if (!gPageBuffer) {
#ifndef CONFIG_MTD_BRCMNAND_EDU
	
	gPageBuffer = kmalloc(sizeof(struct nand_buffers), GFP_KERNEL);

#else
	/* Align on 32B boundary for efficient DMA transfer */
	gPageBuffer = kmalloc(sizeof(struct nand_buffers) + 31, GFP_DMA);
		
#endif
	}
	
	if (!gPageBuffer) {
		return -ENOMEM;
	}

	
	//gPageBuffer = NULL;
	info = kmalloc(sizeof(struct brcmnand_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	gNandInfo[csi] = info;
	memset(info, 0, sizeof(struct brcmnand_info));


	/*
	 * Since platform_data does not send us the number of NAND chips, 
	 * (until it's too late to be useful), we have to count it
	 */
#ifdef BCHP_NAND_CS_NAND_SELECT
	{
		uint32_t nandSelect;
		
		/* Set NAND_CS_NAND_SELECT if not already set by CFE */
		nandSelect = BDEV_RD(BCHP_NAND_CS_NAND_SELECT);
		nandSelect |= 0x100 << cs;
		BDEV_WR(BCHP_NAND_CS_NAND_SELECT, nandSelect);
		
		if (0 == gNumNand) { /* First CS */
			brcmnand_sort_chipSelects(&info->brcmnand);
			gNumNand = info->brcmnand.numchips;
		}
		else  { /* Subsequent CS */
			brcmnand_sort_chipSelects(&info->brcmnand);
			info->brcmnand.numchips = gNumNand;
		}	
	}

#else
	/* Version 1.0 and earlier */
		info->brcmnand.numchips = gNumNand = 1;
#endif
	info->brcmnand.csi = csi;
	

	/* FOr now all devices share the same buffer */


#ifndef CONFIG_MTD_BRCMNAND_EDU
	info->brcmnand.buffers = (struct nand_buffers*) gPageBuffer;
#else
	/* Align on 32B boundary for efficient DMA transfer */
	info->brcmnand.buffers = (struct nand_buffers*) (((unsigned int) gPageBuffer+31) & (~31));
#endif
			
	info->brcmnand.numchips = gNumNand; 
	info->brcmnand.chip_shift = 0; // Only 1 chip
	info->brcmnand.priv = &info->mtd;


	info->mtd.name = dev_name(&pdev->dev);
	info->mtd.priv = &info->brcmnand;
	info->mtd.owner = THIS_MODULE;

/* Enable the following for a flash based bad block table */
	info->brcmnand.options |= NAND_USE_FLASH_BBT;

	//cs = cfg->chip_select;
	

	//brcmnand_sort_chipSelects(&info->brcmnand);

	// Each chip now will have its own BBT (per mtd handle)
	// Problem is we don't know how many CS's we get, until its too late
	if (brcmnand_scan(&info->mtd, cs, gNumNand)) {
		err = -ENXIO;
		goto out_free_info;
	}

PRINTK("Master size=%08llx\n", info->mtd.size);	

#ifdef CONFIG_MTD_PARTITIONS
	/* allow cmdlineparts to override the default map */
	err = parse_mtd_partitions(&info->mtd, part_probe_types,
		&info->parts, 0);
	if (err > 0) {
		info->nr_parts = err;
	} else {
		info->parts = cfg->nr_parts ? cfg->parts : NULL;
		info->nr_parts = cfg->nr_parts;
	}

	// Add MTD partition have a dependency on the BBT
	if (info->nr_parts) // Primary mtd
		brcmnand_add_mtd_partitions(&info->mtd, info->parts, info->nr_parts);
	else  // subsequent NAND only hold 1 partition, and is a brand new mtd device
		brcmnand_add_mtd_device(&info->mtd, csi);
#else
	brcmnand_add_mtd_device(&info->mtd, csi);
#endif

PRINTK("After add_partitions: Master size=%08llx\n", info->mtd.size);	
		
	dev_set_drvdata(&pdev->dev, info);

	csi++;

	return 0;


out_free_info:

	if (gPageBuffer)
		kfree(gPageBuffer);
	kfree(info);
	return err;
}