summaryrefslogtreecommitdiffstats
path: root/linux-2.4.x/drivers/mtd/chips/sharp.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-2.4.x/drivers/mtd/chips/sharp.c')
-rw-r--r--linux-2.4.x/drivers/mtd/chips/sharp.c170
1 files changed, 90 insertions, 80 deletions
diff --git a/linux-2.4.x/drivers/mtd/chips/sharp.c b/linux-2.4.x/drivers/mtd/chips/sharp.c
index 95f0641..f777fb1 100644
--- a/linux-2.4.x/drivers/mtd/chips/sharp.c
+++ b/linux-2.4.x/drivers/mtd/chips/sharp.c
@@ -4,7 +4,7 @@
* Copyright 2000,2001 David A. Schleef <ds@schleef.org>
* 2000,2001 Lineo, Inc.
*
- * $Id: sharp.c,v 1.7 2002/02/13 15:49:07 dwmw2 Exp $
+ * $Id: sharp.c,v 1.18 2006/03/29 08:27:08 dwmw2 Exp $
*
* Devices supported:
* LH28F016SCT Symmetrical block flash memory, 2Mx8
@@ -22,14 +22,16 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
#include <linux/mtd/cfi.h>
#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
#define CMD_RESET 0xffffffff
#define CMD_READ_ID 0x90909090
@@ -62,7 +64,7 @@
#undef AUTOUNLOCK /* automatically unlocks blocks before erasing */
-struct mtd_info *sharp_probe(struct map_info *);
+static struct mtd_info *sharp_probe(struct map_info *);
static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);
@@ -94,18 +96,17 @@ struct sharp_info{
struct flchip chips[1];
};
-struct mtd_info *sharp_probe(struct map_info *map);
static void sharp_destroy(struct mtd_info *mtd);
static struct mtd_chip_driver sharp_chipdrv = {
- probe: sharp_probe,
- destroy: sharp_destroy,
- name: "sharp",
- module: THIS_MODULE
+ .probe = sharp_probe,
+ .destroy = sharp_destroy,
+ .name = "sharp",
+ .module = THIS_MODULE
};
-struct mtd_info *sharp_probe(struct map_info *map)
+static struct mtd_info *sharp_probe(struct map_info *map)
{
struct mtd_info *mtd = NULL;
struct sharp_info *sharp = NULL;
@@ -116,8 +117,10 @@ struct mtd_info *sharp_probe(struct map_info *map)
return NULL;
sharp = kmalloc(sizeof(*sharp), GFP_KERNEL);
- if(!sharp)
+ if(!sharp) {
+ kfree(mtd);
return NULL;
+ }
memset(mtd, 0, sizeof(*mtd));
@@ -152,26 +155,32 @@ struct mtd_info *sharp_probe(struct map_info *map)
map->fldrv = &sharp_chipdrv;
map->fldrv_priv = sharp;
- MOD_INC_USE_COUNT;
+ __module_get(THIS_MODULE);
return mtd;
}
+static inline void sharp_send_cmd(struct map_info *map, unsigned long cmd, unsigned long adr)
+{
+ map_word map_cmd;
+ map_cmd.x[0] = cmd;
+ map_write(map, map_cmd, adr);
+}
+
static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
{
- unsigned long tmp;
+ map_word tmp, read0, read4;
unsigned long base = 0;
- u32 read0, read4;
int width = 4;
- tmp = map->read32(map, base+0);
+ tmp = map_read(map, base+0);
- map->write32(map, CMD_READ_ID, base+0);
+ sharp_send_cmd(map, CMD_READ_ID, base+0);
- read0=map->read32(map, base+0);
- read4=map->read32(map, base+4);
- if(read0 == 0x89898989){
+ read0 = map_read(map, base+0);
+ read4 = map_read(map, base+4);
+ if(read0.x[0] == 0x89898989){
printk("Looks like sharp flash\n");
- switch(read4){
+ switch(read4.x[0]){
case 0xaaaaaaaa:
case 0xa0a0a0a0:
/* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/
@@ -193,16 +202,16 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
return width;
#endif
default:
- printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n",
- read0,read4);
+ printk("Sort-of looks like sharp flash, 0x%08lx 0x%08lx\n",
+ read0.x[0], read4.x[0]);
}
- }else if((map->read32(map, base+0) == CMD_READ_ID)){
+ }else if((map_read(map, base+0).x[0] == CMD_READ_ID)){
/* RAM, probably */
printk("Looks like RAM\n");
- map->write32(map, tmp, base+0);
+ map_write(map, tmp, base+0);
}else{
- printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n",
- read0,read4);
+ printk("Doesn't look like sharp flash, 0x%08lx 0x%08lx\n",
+ read0.x[0], read4.x[0]);
}
return 0;
@@ -211,7 +220,8 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
/* This function returns with the chip->mutex lock held. */
static int sharp_wait(struct map_info *map, struct flchip *chip)
{
- __u16 status;
+ int i;
+ map_word status;
unsigned long timeo = jiffies + HZ;
DECLARE_WAITQUEUE(wait, current);
int adr = 0;
@@ -221,16 +231,14 @@ retry:
switch(chip->state){
case FL_READY:
- map->write32(map,CMD_READ_STATUS,adr);
+ sharp_send_cmd(map, CMD_READ_STATUS, adr);
chip->state = FL_STATUS;
case FL_STATUS:
- status = map->read32(map,adr);
-//printk("status=%08x\n",status);
-
- udelay(100);
- if((status & SR_READY)!=SR_READY){
-//printk(".status=%08x\n",status);
- udelay(100);
+ for(i=0;i<100;i++){
+ status = map_read(map, adr);
+ if((status.x[0] & SR_READY)==SR_READY)
+ break;
+ udelay(1);
}
break;
default:
@@ -252,7 +260,7 @@ retry:
goto retry;
}
- map->write32(map,CMD_RESET, adr);
+ sharp_send_cmd(map, CMD_RESET, adr);
chip->state = FL_READY;
@@ -293,7 +301,7 @@ static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
if(ret<0)
break;
- map->copy_from(map,buf,ofs,thislen);
+ map_copy_from(map,buf,ofs,thislen);
sharp_release(&sharp->chips[chipnum]);
@@ -349,37 +357,39 @@ static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
int timeo;
int try;
int i;
- int status = 0;
+ map_word data, status;
+ status.x[0] = 0;
ret = sharp_wait(map,chip);
for(try=0;try<10;try++){
- map->write32(map,CMD_BYTE_WRITE,adr);
+ sharp_send_cmd(map, CMD_BYTE_WRITE, adr);
/* cpu_to_le32 -> hack to fix the writel be->le conversion */
- map->write32(map,cpu_to_le32(datum),adr);
+ data.x[0] = cpu_to_le32(datum);
+ map_write(map, data, adr);
chip->state = FL_WRITING;
timeo = jiffies + (HZ/2);
- map->write32(map,CMD_READ_STATUS,adr);
+ sharp_send_cmd(map, CMD_READ_STATUS, adr);
for(i=0;i<100;i++){
- status = map->read32(map,adr);
- if((status & SR_READY)==SR_READY)
+ status = map_read(map, adr);
+ if((status.x[0] & SR_READY) == SR_READY)
break;
}
if(i==100){
printk("sharp: timed out writing\n");
}
- if(!(status&SR_ERRORS))
+ if(!(status.x[0] & SR_ERRORS))
break;
- printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status);
+ printk("sharp: error writing byte at addr=%08lx status=%08lx\n", adr, status.x[0]);
- map->write32(map,CMD_CLEAR_STATUS,adr);
+ sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
}
- map->write32(map,CMD_RESET,adr);
+ sharp_send_cmd(map, CMD_RESET, adr);
chip->state = FL_READY;
wake_up(&chip->wq);
@@ -421,8 +431,8 @@ static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
}
}
- if(instr->callback)
- instr->callback(instr);
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
return 0;
}
@@ -431,19 +441,19 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
unsigned long adr)
{
int ret;
- int timeo;
- int status;
+ unsigned long timeo;
+ map_word status;
DECLARE_WAITQUEUE(wait, current);
- map->write32(map,CMD_READ_STATUS,adr);
- status = map->read32(map,adr);
+ sharp_send_cmd(map, CMD_READ_STATUS, adr);
+ status = map_read(map, adr);
timeo = jiffies + HZ;
while(time_before(jiffies, timeo)){
- map->write32(map,CMD_READ_STATUS,adr);
- status = map->read32(map,adr);
- if((status & SR_READY)==SR_READY){
+ sharp_send_cmd(map, CMD_READ_STATUS, adr);
+ status = map_read(map, adr);
+ if((status.x[0] & SR_READY)==SR_READY){
ret = 0;
goto out;
}
@@ -457,12 +467,12 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
remove_wait_queue(&chip->wq, &wait);
//spin_lock_bh(chip->mutex);
-
+
if (signal_pending(current)){
ret = -EINTR;
goto out;
}
-
+
}
ret = -ETIME;
out:
@@ -474,7 +484,7 @@ static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
{
int ret;
//int timeo;
- int status;
+ map_word status;
//int i;
//printk("sharp_erase_oneblock()\n");
@@ -484,26 +494,26 @@ static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
sharp_unlock_oneblock(map,chip,adr);
#endif
- map->write32(map,CMD_BLOCK_ERASE_1,adr);
- map->write32(map,CMD_BLOCK_ERASE_2,adr);
+ sharp_send_cmd(map, CMD_BLOCK_ERASE_1, adr);
+ sharp_send_cmd(map, CMD_BLOCK_ERASE_2, adr);
chip->state = FL_ERASING;
ret = sharp_do_wait_for_ready(map,chip,adr);
if(ret<0)return ret;
- map->write32(map,CMD_READ_STATUS,adr);
- status = map->read32(map,adr);
+ sharp_send_cmd(map, CMD_READ_STATUS, adr);
+ status = map_read(map, adr);
- if(!(status&SR_ERRORS)){
- map->write32(map,CMD_RESET,adr);
+ if(!(status.x[0] & SR_ERRORS)){
+ sharp_send_cmd(map, CMD_RESET, adr);
chip->state = FL_READY;
//spin_unlock_bh(chip->mutex);
return 0;
}
- printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status);
- map->write32(map,CMD_CLEAR_STATUS,adr);
+ printk("sharp: error erasing block at addr=%08lx status=%08lx\n", adr, status.x[0]);
+ sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
//spin_unlock_bh(chip->mutex);
@@ -515,20 +525,20 @@ static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
unsigned long adr)
{
int i;
- int status;
+ map_word status;
- map->write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
- map->write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
+ sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_1, adr);
+ sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_2, adr);
udelay(100);
- status = map->read32(map,adr);
- printk("status=%08x\n",status);
+ status = map_read(map, adr);
+ printk("status=%08lx\n", status.x[0]);
for(i=0;i<1000;i++){
- //map->write32(map,CMD_READ_STATUS,adr);
- status = map->read32(map,adr);
- if((status & SR_READY)==SR_READY)
+ //sharp_send_cmd(map, CMD_READ_STATUS, adr);
+ status = map_read(map, adr);
+ if((status.x[0] & SR_READY) == SR_READY)
break;
udelay(100);
}
@@ -536,14 +546,14 @@ static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
printk("sharp: timed out unlocking block\n");
}
- if(!(status&SR_ERRORS)){
- map->write32(map,CMD_RESET,adr);
+ if(!(status.x[0] & SR_ERRORS)){
+ sharp_send_cmd(map, CMD_RESET, adr);
chip->state = FL_READY;
return;
}
- printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status);
- map->write32(map,CMD_CLEAR_STATUS,adr);
+ printk("sharp: error unlocking block at addr=%08lx status=%08lx\n", adr, status.x[0]);
+ sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
}
#endif
@@ -561,7 +571,7 @@ static int sharp_suspend(struct mtd_info *mtd)
static void sharp_resume(struct mtd_info *mtd)
{
printk("sharp_resume()\n");
-
+
}
static void sharp_destroy(struct mtd_info *mtd)
@@ -570,7 +580,7 @@ static void sharp_destroy(struct mtd_info *mtd)
}
-int __init sharp_probe_init(void)
+static int __init sharp_probe_init(void)
{
printk("MTD Sharp chip driver <ds@lineo.com>\n");