Ejemplo n.º 1
0
/*
 * Main initialization routine
 */
static int __init h1910_init (void)
{
	struct nand_chip *this;
	const char *part_type = 0;
	int mtd_parts_nb = 0;
	struct mtd_partition *mtd_parts = 0;
	void __iomem *nandaddr;
	
	if (!machine_is_h1900())
		return -ENODEV;
		
	nandaddr = (void __iomem *)__ioremap(0x08000000, 0x1000, 0, 1);
	if (!nandaddr) {
		printk("Failed to ioremap nand flash.\n");
		return -ENOMEM;
	}
	
	/* Allocate memory for MTD device structure and private data */
	h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + 
			     sizeof(struct nand_chip),
			     GFP_KERNEL);
	if (!h1910_nand_mtd) {
		printk("Unable to allocate h1910 NAND MTD device structure.\n");
		iounmap ((void *) nandaddr);
		return -ENOMEM;
	}
	
	/* Get pointer to private data */
	this = (struct nand_chip *) (&h1910_nand_mtd[1]);
	
	/* Initialize structures */
	memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info));
	memset((char *) this, 0, sizeof(struct nand_chip));
	
	/* Link the private data with the MTD structure */
	h1910_nand_mtd->priv = this;
	
	/*
	 * Enable VPEN
	 */
	GPSR(37) = GPIO_bit(37);
	
	/* insert callbacks */
	this->IO_ADDR_R = nandaddr;
	this->IO_ADDR_W = nandaddr;
	this->hwcontrol = h1910_hwcontrol;
	this->dev_ready = NULL;	/* unknown whether that was correct or not so we will just do it like this */
	/* 15 us command delay time */
	this->chip_delay = 50;
	this->eccmode = NAND_ECC_SOFT;
	this->options = NAND_NO_AUTOINCR;
	
	/* Scan to find existence of the device */
	if (nand_scan (h1910_nand_mtd, 1)) {
		printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
		kfree (h1910_nand_mtd);
		iounmap ((void *) nandaddr);
		return -ENXIO;
	}
	
#ifdef CONFIG_MTD_CMDLINE_PARTS
	mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, 
						"h1910-nand");
	if (mtd_parts_nb > 0)
	  part_type = "command line";
	else
	  mtd_parts_nb = 0;
#endif
	if (mtd_parts_nb == 0)
	{
		mtd_parts = partition_info;
		mtd_parts_nb = NUM_PARTITIONS;
		part_type = "static";
	}
	
	/* Register the partitions */
	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
	add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb);
	
	/* Return happy */
	return 0;
}
Ejemplo n.º 2
0
/*
 * Main initialization routine
 */
static int __init ep7312_init (void)
{
	struct nand_chip *this;
	const char *part_type = 0;
	int mtd_parts_nb = 0;
	struct mtd_partition *mtd_parts = 0;
	int ep7312_fio_base;
	
	/* Allocate memory for MTD device structure and private data */
	ep7312_mtd = kmalloc(sizeof(struct mtd_info) + 
			     sizeof(struct nand_chip),
			     GFP_KERNEL);
	if (!ep7312_mtd) {
		printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
		return -ENOMEM;
	}
	
	/* map physical adress */
	ep7312_fio_base = (unsigned long)ioremap(ep7312_fio_pbase, SZ_1K);
	if(!ep7312_fio_base) {
		printk("ioremap EDB7312 NAND flash failed\n");
		kfree(ep7312_mtd);
		return -EIO;
	}
	
	/* Get pointer to private data */
	this = (struct nand_chip *) (&ep7312_mtd[1]);
	
	/* Initialize structures */
	memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info));
	memset((char *) this, 0, sizeof(struct nand_chip));
	
	/* Link the private data with the MTD structure */
	ep7312_mtd->priv = this;
	
	/*
	 * Set GPIO Port B control register so that the pins are configured
	 * to be outputs for controlling the NAND flash.
	 */
	clps_writeb(0xf0, ep7312_pxddr);
	
	/* insert callbacks */
	this->IO_ADDR_R = ep7312_fio_base;
	this->IO_ADDR_W = ep7312_fio_base;
	this->hwcontrol = ep7312_hwcontrol;
	this->dev_ready = ep7312_device_ready;
	/* 15 us command delay time */
	this->chip_delay = 15;
	
	/* Scan to find existence of the device */
	if (nand_scan (ep7312_mtd)) {
		iounmap((void *)ep7312_fio_base);
		kfree (ep7312_mtd);
		return -ENXIO;
	}
	
	/* Allocate memory for internal data buffer */
	this->data_buf = kmalloc (sizeof(u_char) * (ep7312_mtd->oobblock + ep7312_mtd->oobsize), GFP_KERNEL);
	if (!this->data_buf) {
		printk("Unable to allocate NAND data buffer for EDB7312.\n");
		iounmap((void *)ep7312_fio_base);
		kfree (ep7312_mtd);
		return -ENOMEM;
	}
	
	/* Allocate memory for internal data buffer */
	this->data_cache = kmalloc (sizeof(u_char) * (ep7312_mtd->oobblock + ep7312_mtd->oobsize), GFP_KERNEL);
	if (!this->data_cache) {
		printk("Unable to allocate NAND data cache for EDB7312.\n");
		kfree (this->data_buf);
		iounmap((void *)ep7312_fio_base);
		kfree (ep7312_mtd);
		return -ENOMEM;
	}
	this->cache_page = -1;
	
#ifdef CONFIG_MTD_CMDLINE_PARTS
	mtd_parts_nb = parse_cmdline_partitions(ep7312_mtd, &mtd_parts, 
						"edb7312-nand");
	if (mtd_parts_nb > 0)
	  part_type = "command line";
	else
	  mtd_parts_nb = 0;
#endif
	if (mtd_parts_nb == 0)
	{
		mtd_parts = partition_info;
		mtd_parts_nb = NUM_PARTITIONS;
		part_type = "static";
	}
	
	/* Register the partitions */
	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
	add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb);
	
	/* Return happy */
	return 0;
}