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

📄 spia.c

📁 最近在國外網站抓到的作業系統 以Arm為基礎去開發的
💻 C
字号:
/*
 *  drivers/mtd/nand/spia.c
 *
 *  Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
 *
 * $Id: spia.c,v 1.1.1.1 2004/12/22 10:02:10 zyu Exp $
 *
 * 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.
 *
 *  Overview:
 *   This is a device driver for the NAND flash device found on the
 *   SPIA board which utilizes the Toshiba TC58V64AFT part. This is
 *   a 64Mibit (8MiB x 8 bits) NAND flash device.
 */

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
#include  <linux/mtd/esram-command.h>

typedef void (* TREAD)( void);	//GFD wuer
TREAD  gfdpread, gfdpwrite, gfdperase;

/*
 * MTD structure for SPIA board
 */
static struct mtd_info *spia_mtd = NULL;

/*
 * Values specific to the SPIA board (used with Garfiled X processor)
 */
#undef MODULE
//#define SPIA_IO_BASE	 0xC0000000	//GFD TEST
//#define SPIA_FIO_BASE	 0xe0000000	//GFD TEST
#define SPIA_IO_ADDR	 =0xd0000000	/* Start of EP7212 IO address space */  //nothing in GFD
#define SPIA_FIO_ADDR	 =0xf0000000	/* Address where flash is mapped */     //nothing in GFD
#define SPIA_PEDR	 0x0080	/*
					 * IO offset to Port E data register
					 * where the CLE, ALE and NCE pins
					 * are wired to.
					 */
#define SPIA_PEDDR	 0x00c0	/*
					 * IO offset to Port E data direction
					 * register so we can control the IO
					 * lines.
					 */

/*
 * Module stuff
 */

//static int spia_io_base = SPIA_IO_BASE;
//static int spia_fio_base = SPIA_FIO_BASE;
static int spia_pedr = SPIA_PEDR;
static int spia_peddr = SPIA_PEDDR;


#define NUM_PARTITIONS 2

/*
 * Main initialization routine
 */
int handle_nand_irq(void)
{	
	unsigned long flags;
	unsigned long j,command;


	//save_flags(flags);  
	//cli();
	
	printk("handle_nand_irq():entering!!!!!\n");
	/* disable interrupts */
	/*
	j = *(volatile unsigned int *)GFD_NAND_IDLE;                         //judge Nand flash compish actions
	while((j&0x1) != 0x00000001UL){  
	           		j = *(volatile unsigned int *)GFD_NAND_IDLE; 
	        }
	*/
	
	j = *(unsigned int *)GFD_NAND_INTR; 
	printk("GFD_NAND_INTR is 0x%x,\n",j);
	           	
	////////////////////////////////////////////////////////
	*(volatile unsigned int *)GFD_NAND_INTR = 0x0;
	printk("handle_nand_irq():Nand interrupt cleared!.\n ");
	           	
	j = *(unsigned int *)GFD_NAND_INTR; 
	printk("GFD_NAND_INTR is 0x%x,\n",j);
	
	

	
	command = *(unsigned int *)GFD_NAND_COM; 
	printk("GFD_NAND_COM is 0x%x,\n",j);

	
	switch((unsigned int)(command && 0xff)){
		case 0x00: printk("read error!");break;
		case 0x60: printk("erase error!");break;
		case 0x80: printk("write error!");break;

		default:{  printk("other error!");
	           	/*
	           	j = *(unsigned int *)GFD_NAND_ADDR; 
	           	printk("GFD_NAND_ADDR is 0x%x,\n",j);
	           	j = *(unsigned int *)GFD_NAND_CONF; 
	           	printk("GFD_NAND_CONF is 0x%x,\n",j);
	           	j = *(unsigned int *)DMACC0SrcAddr; 
	           	printk("DMACC0SrcAddr is 0x%x,\n",j);
	           	j = *(unsigned int *)DMACC0DestAddr; 
	           	printk("DMACC0DestAddr is 0x%x,\n",j);
	           	j = *(unsigned int *)DMACC0Control; 
	           	printk("DMACC0Control is 0x%x,\n",j);
	           	j = *(unsigned int *)DMACC0Configuration; 
	           	printk("DMACC0Configuration is 0x%x,\n",j);
	           	j = *(unsigned int *)GFD_NAND_ERRORADDR1; 
	           	printk("GFD_NAND_ERRORADDR1 is 0x%x,\n",j);
	           	j = *(unsigned int *)GFD_NAND_ERRORADDR2; 
	           	printk("GFD_NAND_ERRORADDR2 is 0x%x,\n",j);
	           	//////////////////////////////////////////////////////////////
			*/
			} 
		}
	 
	
	//restore_flags(flags);  /* Enable interrupts */
	return 0;
}

int spia_init (void)
{
	struct nand_chip *this;
	int err,i;
	
	unsigned int  *px, *py;
	
	err = request_irq(GFD_INTSRC_EMI, handle_nand_irq,0,"nand irq",NULL);
	if(err){
		disable_irq(GFD_INTSRC_EMI);
		printk(" Error. Cannot attach IRQ %d to nand flash device\n", GFD_INTSRC_EMI);
		return err;
	}
	
	/* Allocate memory for MTD device structure and private data */
	spia_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
				GFP_KERNEL);
	if (!spia_mtd) {
		printk ("Unable to allocate Garfield NAND MTD device structure.\n");
		return -ENOMEM;
	}

	printk ("Allocate memory done!.\n");
	
	/* Get pointer to private data */
	this = (struct nand_chip *) (&spia_mtd[1]);
	
      /* Initialize structures */
	memset((char *) spia_mtd, 0, sizeof(struct mtd_info));
	memset((char *) this, 0, sizeof(struct nand_chip));

	/* Link the private data with the MTD structure */
	spia_mtd->priv = this;


	/*
	 * Set GPIO Port E control register so that the pins are configured
	 * to be outputs for controlling the NAND flash.
	 */
	//(*(volatile unsigned char *) (spia_io_base + spia_peddr)) = 0x07;

	 init_waitqueue_head(&(this->wq));

	/* Set address of NAND IO lines */
	this->IO_ADDR = GFD_NAND_COM;   						//Gfd Nand: data register                                                
	this->CTRL_ADDR = GFD_NAND_COM;                                         			//>								//Control register
	//this->CLE = 0x01;
	//this->ALE = 0x02;
	//this->NCE = 0x04;

	printk("This->IO_ADDR: %x.\n",this->IO_ADDR);
	printk("This->CTRL_ADDR: %x.\n",this->CTRL_ADDR);
	printk("This->wq: %x .\n", &this->wq);
	printk("This->wq.task_list.next: %x .\n", &this->wq.task_list.next);
	printk("This->wq.task_list.prev: %x .\n", &this->wq.task_list.prev);

	/* Scan to find existence of the device */
	if (nand_scan (spia_mtd)) {
		kfree (spia_mtd);
		printk ("Garfield III Nand Flash:Crying,no mtd detected :(  \n");      	//Gfd Nand
		
		return -ENXIO;
	}

	/* Allocate memory for internal data buffer */
	this->data_buf = kmalloc (sizeof(u_char) * (spia_mtd->oobblock + spia_mtd->oobsize), GFP_KERNEL);
	if (!this->data_buf) {
		printk ("Unable to allocate NAND data buffer for Garfield.\n");
		kfree (spia_mtd);
		return -ENOMEM;
	}

	
	/* Register the partitions */
	add_mtd_partitions(spia_mtd, gfd_intel_partitions, NUM_PARTITIONS);

       printk ("Garfield III: leaving  spia_init{} .....\n");  

	 /****************************/
	 px = (volatile unsigned int *)esram_read;
	 py = (volatile unsigned int *)0x1fff0000;
	 for(i=0; i<600; i++){
	 	*py++ = *px++;
	 	}
	 (volatile unsigned int)gfdpread = 0x1fff0000;
	 (volatile unsigned int)gfdperase = 0x1fff0020;
	 (volatile unsigned int)gfdpwrite = 0x1fff0044;
	
	 /*****************************/
	
	 
	/* Return happy */
	return 0;
}
//module_init(spia_init);

/*
 * Clean up routine
 */



#ifdef MODULE
static void __exit spia_cleanup (void)
{
	struct nand_chip *this = (struct nand_chip *) &spia_mtd[1];

	/* Unregister the device */
	del_mtd_device (spia_mtd);

	/* Free internal data buffer */
	kfree (this->data_buf);

	/* Free the MTD device structure */
	kfree (spia_mtd);
}
module_exit(spia_cleanup);
#endif

MODULE_LICENSE("GPL");
MODULE_AUTHOR("CNASIC wuer changed ");
MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on Garfield board");
__initcall(spia_init);

⌨️ 快捷键说明

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