📄 spia.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 + -