summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Kunze <thommycheck@gmx.de>2008-10-18 02:04:35 +0200
committerThomas Kunze <thommycheck@gmx.de>2008-10-18 02:06:07 +0200
commit958429dd9f7b355a6e8358265ca0f056839b729c (patch)
treea1189245ca359642cf5b7795613cce3245e32b74
parent869781d0526120e8881d18f812e58327b4568f28 (diff)
linux-kexecboot: use hacked sharp-flash driver
-rw-r--r--packages/kexecboot/linux-kexecboot-2.6.26/collie.patch883
-rw-r--r--packages/kexecboot/linux-kexecboot-2.6.26/collie/defconfig13
-rw-r--r--packages/kexecboot/linux-kexecboot_2.6.26.bb2
3 files changed, 795 insertions, 103 deletions
diff --git a/packages/kexecboot/linux-kexecboot-2.6.26/collie.patch b/packages/kexecboot/linux-kexecboot-2.6.26/collie.patch
index 6dad0027c6..750be8ecf3 100644
--- a/packages/kexecboot/linux-kexecboot-2.6.26/collie.patch
+++ b/packages/kexecboot/linux-kexecboot-2.6.26/collie.patch
@@ -1,8 +1,8 @@
-diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index c7ad324..daa2e0a 100644
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -998,7 +998,7 @@ config CPU_FREQ_SA1100
+Index: linux-2.6.26/arch/arm/Kconfig
+===================================================================
+--- linux-2.6.26.orig/arch/arm/Kconfig 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/arch/arm/Kconfig 2008-10-17 18:15:31.391792839 +0200
+@@ -967,7 +967,7 @@
config CPU_FREQ_SA1110
bool
@@ -11,11 +11,24 @@ index c7ad324..daa2e0a 100644
default y
config CPU_FREQ_INTEGRATOR
-diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c
-index e508028..36f726c 100644
---- a/arch/arm/mach-sa1100/dma.c
-+++ b/arch/arm/mach-sa1100/dma.c
-@@ -39,7 +39,7 @@ typedef struct {
+Index: linux-2.6.26/arch/arm/mach-sa1100/collie.c
+===================================================================
+--- linux-2.6.26.orig/arch/arm/mach-sa1100/collie.c 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/arch/arm/mach-sa1100/collie.c 2008-10-17 18:15:31.391792839 +0200
+@@ -206,7 +206,7 @@
+ }
+
+ static struct flash_platform_data collie_flash_data = {
+- .map_name = "cfi_probe",
++ .map_name = "sharp",
+ .set_vpp = collie_set_vpp,
+ .parts = collie_partitions,
+ .nr_parts = ARRAY_SIZE(collie_partitions),
+Index: linux-2.6.26/arch/arm/mach-sa1100/dma.c
+===================================================================
+--- linux-2.6.26.orig/arch/arm/mach-sa1100/dma.c 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/arch/arm/mach-sa1100/dma.c 2008-10-17 18:15:31.399789199 +0200
+@@ -39,7 +39,7 @@
static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS];
@@ -24,11 +37,11 @@ index e508028..36f726c 100644
static irqreturn_t dma_irq_handler(int irq, void *dev_id)
-diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
-index 9caed30..79e19bf 100644
---- a/drivers/input/keyboard/locomokbd.c
-+++ b/drivers/input/keyboard/locomokbd.c
-@@ -265,6 +265,7 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev)
+Index: linux-2.6.26/drivers/input/keyboard/locomokbd.c
+===================================================================
+--- linux-2.6.26.orig/drivers/input/keyboard/locomokbd.c 2008-10-17 18:13:16.000000000 +0200
++++ linux-2.6.26/drivers/input/keyboard/locomokbd.c 2008-10-17 18:15:31.403791239 +0200
+@@ -272,6 +272,7 @@
for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
set_bit(locomokbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
@@ -36,11 +49,11 @@ index 9caed30..79e19bf 100644
/* attempt to get the interrupt */
err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
-diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
-index 9f93c29..33fc5d6 100644
---- a/drivers/mfd/Kconfig
-+++ b/drivers/mfd/Kconfig
-@@ -72,4 +72,10 @@ config MCP_UCB1200_TS
+Index: linux-2.6.26/drivers/mfd/Kconfig
+===================================================================
+--- linux-2.6.26.orig/drivers/mfd/Kconfig 2008-10-17 18:13:21.000000000 +0200
++++ linux-2.6.26/drivers/mfd/Kconfig 2008-10-17 18:15:31.403791239 +0200
+@@ -77,4 +77,10 @@
tristate "Touchscreen interface support"
depends on MCP_UCB1200 && INPUT
@@ -51,11 +64,11 @@ index 9f93c29..33fc5d6 100644
+ Driver for touchscreen on collie - sharp sl-5500.
+
endmenu
-diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
-index 33daa2f..0885ccd 100644
---- a/drivers/mfd/Makefile
-+++ b/drivers/mfd/Makefile
-@@ -16,7 +16,7 @@ obj-$(CONFIG_MCP) += mcp-core.o
+Index: linux-2.6.26/drivers/mfd/Makefile
+===================================================================
+--- linux-2.6.26.orig/drivers/mfd/Makefile 2008-10-17 18:13:21.000000000 +0200
++++ linux-2.6.26/drivers/mfd/Makefile 2008-10-17 18:15:31.407791679 +0200
+@@ -14,7 +14,7 @@
obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
@@ -64,11 +77,10 @@ index 33daa2f..0885ccd 100644
ifeq ($(CONFIG_SA1100_ASSABET),y)
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
endif
-diff --git a/drivers/mfd/collie-ts.c b/drivers/mfd/collie-ts.c
-new file mode 100644
-index 0000000..ddde5fc
---- /dev/null
-+++ b/drivers/mfd/collie-ts.c
+Index: linux-2.6.26/drivers/mfd/collie-ts.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.26/drivers/mfd/collie-ts.c 2008-10-17 18:15:31.415790559 +0200
@@ -0,0 +1,449 @@
+/*
+ * Touchscreen driver for UCB1x00-based touchscreens
@@ -103,9 +115,9 @@ index 0000000..ddde5fc
+#include <linux/freezer.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
++#include <linux/semaphore.h>
+
+#include <asm/dma.h>
-+#include <asm/semaphore.h>
+#include <asm/arch/collie.h>
+#include <asm/mach-types.h>
+
@@ -519,10 +531,10 @@ index 0000000..ddde5fc
+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION("UCB1x00 touchscreen driver");
+MODULE_LICENSE("GPL");
-diff --git a/drivers/mfd/ucb1x00.h b/drivers/mfd/ucb1x00.h
-index a8ad8a0..137b043 100644
---- a/drivers/mfd/ucb1x00.h
-+++ b/drivers/mfd/ucb1x00.h
+Index: linux-2.6.26/drivers/mfd/ucb1x00.h
+===================================================================
+--- linux-2.6.26.orig/drivers/mfd/ucb1x00.h 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/drivers/mfd/ucb1x00.h 2008-10-17 18:15:31.415790559 +0200
@@ -34,7 +34,10 @@
#define UCB_IE_TCLIP (1 << 14)
#define UCB_IE_ACLIP (1 << 15)
@@ -534,28 +546,719 @@ index a8ad8a0..137b043 100644
#define UCB_TC_A 0x05
#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
-diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
-index c7d5a52..215bec2 100644
---- a/drivers/mtd/maps/sa1100-flash.c
-+++ b/drivers/mtd/maps/sa1100-flash.c
-@@ -210,6 +210,12 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r
+Index: linux-2.6.26/drivers/mtd/chips/Kconfig
+===================================================================
+--- linux-2.6.26.orig/drivers/mtd/chips/Kconfig 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/drivers/mtd/chips/Kconfig 2008-10-17 18:15:31.419791479 +0200
+@@ -239,5 +239,13 @@
+ used for XIP purposes. If you're not sure what this is all about
+ then say N.
+
++config MTD_SHARP
++ tristate "pre-CFI Sharp chip support"
++ depends on MTD
++ help
++ This option enables support for flash chips using Sharp-compatible
++ commands, including some which are not CFI-compatible and hence
++ cannot be used with the CONFIG_MTD_CFI_INTELxxx options.
++
+ endmenu
+
+Index: linux-2.6.26/drivers/mtd/chips/Makefile
+===================================================================
+--- linux-2.6.26.orig/drivers/mtd/chips/Makefile 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/drivers/mtd/chips/Makefile 2008-10-17 18:15:31.419791479 +0200
+@@ -12,4 +12,5 @@
+ obj-$(CONFIG_MTD_JEDECPROBE) += jedec_probe.o
+ obj-$(CONFIG_MTD_RAM) += map_ram.o
+ obj-$(CONFIG_MTD_ROM) += map_rom.o
++obj-$(CONFIG_MTD_SHARP) += sharp.o
+ obj-$(CONFIG_MTD_ABSENT) += map_absent.o
+Index: linux-2.6.26/drivers/mtd/chips/sharp.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.26/drivers/mtd/chips/sharp.c 2008-10-17 18:15:31.423790399 +0200
+@@ -0,0 +1,645 @@
++/*
++ * MTD chip driver for pre-CFI Sharp flash chips
++ *
++ * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
++ * 2000,2001 Lineo, Inc.
++ *
++ * $Id: sharp.c,v 1.17 2005/11/29 14:28:28 gleixner Exp $
++ *
++ * Devices supported:
++ * LH28F016SCT Symmetrical block flash memory, 2Mx8
++ * LH28F008SCT Symmetrical block flash memory, 1Mx8
++ *
++ * Documentation:
++ * http://www.sharpmeg.com/datasheets/memic/flashcmp/
++ * http://www.sharpmeg.com/datasheets/memic/flashcmp/01symf/16m/016sctl9.pdf
++ * 016sctl9.pdf
++ *
++ * Limitations:
++ * This driver only supports 4x1 arrangement of chips.
++ * Not tested on anything but PowerPC.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/init.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>
++
++#define CMD_RESET 0xffffffff
++#define CMD_READ_ID 0x90909090
++#define CMD_READ_STATUS 0x70707070
++#define CMD_CLEAR_STATUS 0x50505050
++#define CMD_BLOCK_ERASE_1 0x20202020
++#define CMD_BLOCK_ERASE_2 0xd0d0d0d0
++#define CMD_BYTE_WRITE 0x40404040
++#define CMD_SUSPEND 0xb0b0b0b0
++#define CMD_RESUME 0xd0d0d0d0
++#define CMD_SET_BLOCK_LOCK_1 0x60606060
++#define CMD_SET_BLOCK_LOCK_2 0x01010101
++#define CMD_SET_MASTER_LOCK_1 0x60606060
++#define CMD_SET_MASTER_LOCK_2 0xf1f1f1f1
++#define CMD_CLEAR_BLOCK_LOCKS_1 0x60606060
++#define CMD_CLEAR_BLOCK_LOCKS_2 0xd0d0d0d0
++
++#define SR_READY 0x80808080 // 1 = ready
++#define SR_ERASE_SUSPEND 0x40404040 // 1 = block erase suspended
++#define SR_ERROR_ERASE 0x20202020 // 1 = error in block erase or clear lock bits
++#define SR_ERROR_WRITE 0x10101010 // 1 = error in byte write or set lock bit
++#define SR_VPP 0x08080808 // 1 = Vpp is low
++#define SR_WRITE_SUSPEND 0x04040404 // 1 = byte write suspended
++#define SR_PROTECT 0x02020202 // 1 = lock bit set
++#define SR_RESERVED 0x01010101
++
++#define SR_ERRORS (SR_ERROR_ERASE|SR_ERROR_WRITE|SR_VPP|SR_PROTECT)
++
++#define BLOCK_MASK 0xfffe0000
++
++/* Configuration options */
++
++#define AUTOUNLOCK /* automatically unlocks blocks before erasing */
++
++static struct mtd_info *sharp_probe(struct map_info *);
++
++static int sharp_probe_map(struct map_info *map, struct mtd_info *mtd);
++
++static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
++ size_t *retlen, u_char *buf);
++static int sharp_write(struct mtd_info *mtd, loff_t from, size_t len,
++ size_t *retlen, const u_char *buf);
++static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr);
++static void sharp_sync(struct mtd_info *mtd);
++static int sharp_suspend(struct mtd_info *mtd);
++static void sharp_resume(struct mtd_info *mtd);
++static void sharp_destroy(struct mtd_info *mtd);
++
++static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
++ unsigned long adr, __u32 datum);
++static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
++ unsigned long adr);
++#ifdef AUTOUNLOCK
++static inline void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
++ unsigned long adr);
++#endif
++
++
++struct sharp_info{
++ struct flchip *chip;
++ int bogus;
++ int chipshift;
++ int numchips;
++ struct flchip chips[1];
++};
++
++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
++};
++
++static void sharp_udelay(unsigned long i) {
++ if (in_interrupt()) {
++ udelay(i);
++ } else {
++ schedule();
++ }
++}
++
++static struct mtd_info *sharp_probe(struct map_info *map)
++{
++ struct mtd_info *mtd = NULL;
++ struct sharp_info *sharp = NULL;
++ int width;
++
++ mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);
++ if(!mtd)
++ return NULL;
++
++ sharp = kzalloc(sizeof(*sharp), GFP_KERNEL);
++ if(!sharp) {
++ kfree(mtd);
++ return NULL;
++ }
++
++ width = sharp_probe_map(map,mtd);
++ if(!width){
++ kfree(mtd);
++ kfree(sharp);
++ return NULL;
++ }
++
++ mtd->priv = map;
++ mtd->type = MTD_NORFLASH;
++ mtd->erase = sharp_erase;
++ mtd->read = sharp_read;
++ mtd->write = sharp_write;
++ mtd->sync = sharp_sync;
++ mtd->suspend = sharp_suspend;
++ mtd->resume = sharp_resume;
++ mtd->flags = MTD_CAP_NORFLASH;
++ mtd->writesize = 1;
++ mtd->name = map->name;
++
++ sharp->chipshift = 24;
++ sharp->numchips = 1;
++ sharp->chips[0].start = 0;
++ sharp->chips[0].state = FL_READY;
++ sharp->chips[0].mutex = &sharp->chips[0]._spinlock;
++ sharp->chips[0].word_write_time = 0;
++ init_waitqueue_head(&sharp->chips[0].wq);
++ spin_lock_init(&sharp->chips[0]._spinlock);
++
++ map->fldrv = &sharp_chipdrv;
++ map->fldrv_priv = sharp;
++
++ __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)
++{
++ map_word tmp, read0, read4;
++ unsigned long base = 0;
++ int width = 4;
++
++ tmp = map_read(map, base+0);
++
++ sharp_send_cmd(map, CMD_READ_ID, base+0);
++
++ read0 = map_read(map, base+0);
++ read4 = map_read(map, base+4);
++ if (read0.x[0] == 0x00b000b0) {
++ printk("Sharp chip, %lx, %lx, width = %d\n", read0.x[0], read4.x[0], width);
++ /* Prints b000b0, b000b0, width = 4 on collie */
++ switch(read4.x[0]){
++ case 0xaaaaaaaa:
++ case 0xa0a0a0a0:
++ /* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/
++ /* a0 - LH28F016SCT-Z4 2Mx8, 32 64k blocks*/
++ mtd->erasesize = 0x10000 * width;
++ mtd->size = 0x200000 * width;
++ return width;
++ case 0xa6a6a6a6:
++ /* a6 - LH28F008SCT-L12 1Mx8, 16 64k blocks*/
++ /* a6 - LH28F008SCR-L85 1Mx8, 16 64k blocks*/
++ mtd->erasesize = 0x10000 * width;
++ mtd->size = 0x100000 * width;
++ return width;
++ case 0x00b000b0:
++ /* a6 - LH28F640BFHE 8 64k * 2 chip blocks*/
++ mtd->erasesize = 0x10000 * width / 2;
++ mtd->size = 0x800000 * width / 2;
++ return width;
++ default:
++ printk("Sort-of looks like sharp flash, 0x%08lx 0x%08lx\n",
++ read0.x[0], read4.x[0]);
++ }
++ } else if ((map_read(map, base+0).x[0] == CMD_READ_ID)){
++ /* RAM, probably */
++ printk("Looks like RAM\n");
++ map_write(map, tmp, base+0);
++ }else{
++ printk("Doesn't look like sharp flash, 0x%08lx 0x%08lx\n",
++ read0.x[0], read4.x[0]);
++ }
++
++ return 0;
++}
++
++/* This function returns with the chip->mutex lock held. */
++static int sharp_wait(struct map_info *map, struct flchip *chip)
++{
++ map_word status;
++ unsigned long timeo = jiffies + HZ;
++ DECLARE_WAITQUEUE(wait, current);
++ int adr = 0;
++
++retry:
++ spin_lock_bh(chip->mutex);
++
++ switch (chip->state) {
++ case FL_READY:
++ sharp_send_cmd(map, CMD_READ_STATUS, adr);
++ chip->state = FL_STATUS;
++ case FL_STATUS:
++ status = map_read(map, adr);
++ if ((status.x[0] & SR_READY) == SR_READY)
++ break;
++ spin_unlock_bh(chip->mutex);
++ if (time_after(jiffies, timeo)) {
++ printk("Waiting for chip to be ready timed out in erase\n");
++ return -EIO;
++ }
++ sharp_udelay(1);
++ goto retry;
++ default:
++ set_current_state(TASK_INTERRUPTIBLE);
++ add_wait_queue(&chip->wq, &wait);
++
++ spin_unlock_bh(chip->mutex);
++
++ sharp_udelay(1);
++
++ set_current_state(TASK_RUNNING);
++ remove_wait_queue(&chip->wq, &wait);
++
++ if(signal_pending(current))
++ return -EINTR;
++
++ timeo = jiffies + HZ;
++
++ goto retry;
++ }
++
++ sharp_send_cmd(map, CMD_RESET, adr);
++
++ chip->state = FL_READY;
++
++ return 0;
++}
++
++static void sharp_release(struct flchip *chip)
++{
++ wake_up(&chip->wq);
++ spin_unlock_bh(chip->mutex);
++}
++
++static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
++ size_t *retlen, u_char *buf)
++{
++ struct map_info *map = mtd->priv;
++ struct sharp_info *sharp = map->fldrv_priv;
++ int chipnum;
++ int ret = 0;
++ int ofs = 0;
++
++ chipnum = (from >> sharp->chipshift);
++ ofs = from & ((1 << sharp->chipshift)-1);
++
++ *retlen = 0;
++
++ while(len){
++ unsigned long thislen;
++
++ if(chipnum>=sharp->numchips)
++ break;
++
++ thislen = len;
++ if(ofs+thislen >= (1<<sharp->chipshift))
++ thislen = (1<<sharp->chipshift) - ofs;
++
++ ret = sharp_wait(map,&sharp->chips[chipnum]);
++ if(ret<0)
++ break;
++
++ map_copy_from(map,buf,ofs,thislen);
++
++ sharp_release(&sharp->chips[chipnum]);
++
++ *retlen += thislen;
++ len -= thislen;
++ buf += thislen;
++
++ ofs = 0;
++ chipnum++;
++ }
++ return ret;
++}
++
++static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len,
++ size_t *retlen, const u_char *buf)
++{
++ struct map_info *map = mtd->priv;
++ struct sharp_info *sharp = map->fldrv_priv;
++ int ret = 0;
++ int i,j;
++ int chipnum;
++ unsigned long ofs;
++ union { u32 l; unsigned char uc[4]; } tbuf;
++
++ *retlen = 0;
++
++ while(len){
++ tbuf.l = 0xffffffff;
++ chipnum = to >> sharp->chipshift;
++ ofs = to & ((1<<sharp->chipshift)-1);
++
++ j=0;
++ for(i=ofs&3;i<4 && len;i++){
++ tbuf.uc[i] = *buf;
++ buf++;
++ to++;
++ len--;
++ j++;
++ }
++ sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l);
++ if(ret<0)
++ return ret;
++ (*retlen)+=j;
++ }
++
++ return 0;
++}
++
++static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
++ unsigned long adr, __u32 datum)
++{
++ int ret;
++ int try;
++ int i;
++ map_word data, status;
++
++ status.x[0] = 0;
++ ret = sharp_wait(map,chip);
++ if (ret < 0)
++ return ret;
++
++ for (try=0; try<10; try++) {
++ long timeo;
++
++ sharp_send_cmd(map, CMD_BYTE_WRITE, adr);
++ /* cpu_to_le32 -> hack to fix the writel be->le conversion */
++ data.x[0] = cpu_to_le32(datum);
++ map_write(map, data, adr);
++
++ chip->state = FL_WRITING;
++ timeo = jiffies + (HZ/2);
++
++ sharp_send_cmd(map, CMD_READ_STATUS, adr);
++ for(i=0;i<100;i++){
++ status = map_read(map, adr);
++ if((status.x[0] & SR_READY) == SR_READY)
++ break;
++ }
++#ifdef AUTOUNLOCK
++ if (status.x[0] & SR_PROTECT) { /* lock block */
++ sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
++ sharp_unlock_oneblock(map,chip,adr);
++ sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
++ sharp_send_cmd(map, CMD_RESET, adr);
++ continue;
++ }
++#endif
++ if(i==100){
++ printk("sharp: timed out writing\n");
++ }
++
++ if (!(status.x[0] & SR_ERRORS))
++ break;
++
++ printk("sharp: error writing byte at addr=%08lx status=%08lx\n", adr, status.x[0]);
++
++ sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
++ }
++ sharp_send_cmd(map, CMD_RESET, adr);
++ chip->state = FL_READY;
++
++ sharp_release(chip);
++
++ return 0;
++}
++
++static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
++{
++ struct map_info *map = mtd->priv;
++ struct sharp_info *sharp = map->fldrv_priv;
++ unsigned long adr,len;
++ int chipnum, ret=0;
++
++ if(instr->addr & (mtd->erasesize - 1))
++ return -EINVAL;
++ if(instr->len & (mtd->erasesize - 1))
++ return -EINVAL;
++ if(instr->len + instr->addr > mtd->size)
++ return -EINVAL;
++
++ chipnum = instr->addr >> sharp->chipshift;
++ adr = instr->addr & ((1<<sharp->chipshift)-1);
++ len = instr->len;
++
++ while(len){
++ ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr);
++ if(ret)return ret;
++
++ if (adr >= 0xfe0000) {
++ adr += mtd->erasesize / 8;
++ len -= mtd->erasesize / 8;
++ } else {
++ adr += mtd->erasesize;
++ len -= mtd->erasesize;
++ }
++ if(adr >> sharp->chipshift){
++ adr = 0;
++ chipnum++;
++ if(chipnum>=sharp->numchips)
++ break;
++ }
++ }
++
++ instr->state = MTD_ERASE_DONE;
++ mtd_erase_callback(instr);
++
++ return 0;
++}
++
++static inline int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
++ unsigned long adr)
++{
++ int ret;
++ unsigned long timeo;
++ map_word status;
++ DECLARE_WAITQUEUE(wait, current);
++
++ sharp_send_cmd(map, CMD_READ_STATUS, adr);
++ status = map_read(map, adr);
++
++ timeo = jiffies + HZ * 10;
++
++ while (time_before(jiffies, timeo)) {
++ 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;
++ }
++ set_current_state(TASK_INTERRUPTIBLE);
++ add_wait_queue(&chip->wq, &wait);
++
++ spin_unlock_bh(chip->mutex);
++
++ schedule_timeout(1);
++ schedule();
++
++ spin_lock_bh(chip->mutex);
++
++ remove_wait_queue(&chip->wq, &wait);
++ set_current_state(TASK_RUNNING);
++ }
++ ret = -ETIME;
++out:
++ return ret;
++}
++
++static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
++ unsigned long adr)
++{
++ int ret;
++ map_word status;
++
++ ret = sharp_wait(map,chip);
++ if (ret < 0)
++ return ret;
++
++#ifdef AUTOUNLOCK
++ /* This seems like a good place to do an unlock */
++ sharp_unlock_oneblock(map,chip,adr);
++#endif
++
++ 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) {
++ spin_unlock_bh(chip->mutex);
++ return ret;
++ }
++
++ sharp_send_cmd(map, CMD_READ_STATUS, adr);
++ status = map_read(map, 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=%08lx\n", adr, status.x[0]);
++ sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
++
++ sharp_release(chip);
++
++ return -EIO;
++}
++
++#ifdef AUTOUNLOCK
++static inline void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
++ unsigned long adr)
++{
++ map_word status;
++
++ sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_1, adr & BLOCK_MASK);
++ sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_2, adr & BLOCK_MASK);
++
++ sharp_do_wait_for_ready(map,chip,adr);
++
++ status = map_read(map, 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=%08lx\n", adr, status.x[0]);
++ sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
++}
++#endif
++
++static void sharp_sync(struct mtd_info *mtd)
++{
++}
++
++static int sharp_suspend(struct mtd_info *mtd)
++{
++ struct map_info *map = mtd->priv;
++ struct sharp_info *sharp = map->fldrv_priv;
++ int i;
++ struct flchip *chip;
++ int ret = 0;
++
++ for (i = 0; !ret && i < sharp->numchips; i++) {
++ chip = &sharp->chips[i];
++ ret = sharp_wait(map,chip);
++
++ if (ret) {
++ ret = -EAGAIN;
++ } else {
++ chip->state = FL_PM_SUSPENDED;
++ spin_unlock_bh(chip->mutex);
++ }
++ }
++ return ret;
++}
++
++static void sharp_resume(struct mtd_info *mtd)
++{
++ struct map_info *map = mtd->priv;
++ struct sharp_info *sharp = map->fldrv_priv;
++ int i;
++ struct flchip *chip;
++
++ for (i = 0; i < sharp->numchips; i++) {
++ chip = &sharp->chips[i];
++
++ spin_lock_bh(chip->mutex);
++
++ if (chip->state == FL_PM_SUSPENDED) {
++ /* We need to force it back to a known state */
++ sharp_send_cmd(map, CMD_RESET, chip->start);
++ chip->state = FL_READY;
++ wake_up(&chip->wq);
++ }
++
++ spin_unlock_bh(chip->mutex);
++ }
++}
++
++static void sharp_destroy(struct mtd_info *mtd)
++{
++ struct map_info *map = mtd->priv;
++ struct sharp_info *sharp = map->fldrv_priv;
++
++ kfree(sharp);
++}
++
++static int __init sharp_probe_init(void)
++{
++ printk("MTD Sharp chip driver <ds@lineo.com>\n");
++
++ register_mtd_chip_driver(&sharp_chipdrv);
++
++ return 0;
++}
++
++static void __exit sharp_probe_exit(void)
++{
++ unregister_mtd_chip_driver(&sharp_chipdrv);
++}
++
++module_init(sharp_probe_init);
++module_exit(sharp_probe_exit);
++
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("David Schleef <ds@schleef.org>");
++MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips");
+Index: linux-2.6.26/drivers/mtd/maps/Kconfig
+===================================================================
+--- linux-2.6.26.orig/drivers/mtd/maps/Kconfig 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/drivers/mtd/maps/Kconfig 2008-10-17 18:15:31.431789839 +0200
+@@ -392,7 +392,7 @@
+
+ config MTD_SA1100
+ tristate "CFI Flash device mapped on StrongARM SA11x0"
+- depends on MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS
++ depends on (MTD_CFI || MTD_SHARP) && ARCH_SA1100 && MTD_PARTITIONS
+ help
+ This enables access to the flash chips on most platforms based on
+ the SA1100 and SA1110, including the Assabet and the Compaq iPAQ.
+Index: linux-2.6.26/drivers/mtd/maps/sa1100-flash.c
+===================================================================
+--- linux-2.6.26.orig/drivers/mtd/maps/sa1100-flash.c 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/drivers/mtd/maps/sa1100-flash.c 2008-10-17 18:15:31.431789839 +0200
+@@ -210,6 +210,12 @@
goto err;
}
subdev->mtd->owner = THIS_MODULE;
+
+#ifdef CONFIG_SA1100_COLLIE
+ /* collie flash starts locked */
-+ if (subdev->mtd->unlock)
-+ subdev->mtd->unlock(subdev->mtd, 0xc0000, subdev->mtd->size - 0xc0000);
++// if (subdev->mtd->unlock)
++// subdev->mtd->unlock(subdev->mtd, 0xc0000, subdev->mtd->size - 0xc0000);
+#endif
printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, "
"%d-bit\n", phys, subdev->mtd->size >> 20,
-diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
-index 3b4e55c..0ae741d 100644
---- a/drivers/net/wireless/hostap/hostap_cs.c
-+++ b/drivers/net/wireless/hostap/hostap_cs.c
-@@ -35,7 +35,7 @@ static int ignore_cis_vcc;
+Index: linux-2.6.26/drivers/net/wireless/hostap/hostap_cs.c
+===================================================================
+--- linux-2.6.26.orig/drivers/net/wireless/hostap/hostap_cs.c 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/drivers/net/wireless/hostap/hostap_cs.c 2008-10-17 18:15:31.435790279 +0200
+@@ -35,7 +35,7 @@
module_param(ignore_cis_vcc, int, 0444);
MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
@@ -564,7 +1267,7 @@ index 3b4e55c..0ae741d 100644
/* struct local_info::hw_priv */
struct hostap_cs_priv {
dev_node_t node;
-@@ -499,11 +499,13 @@ static int hostap_cs_probe(struct pcmcia_device *p_dev)
+@@ -499,11 +499,13 @@
PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
p_dev->conf.IntType = INT_MEMORY_AND_IO;
@@ -579,10 +1282,10 @@ index 3b4e55c..0ae741d 100644
return ret;
}
-diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
-index 13d5882..6f24d66 100644
---- a/drivers/net/wireless/hostap/hostap_hw.c
-+++ b/drivers/net/wireless/hostap/hostap_hw.c
+Index: linux-2.6.26/drivers/net/wireless/hostap/hostap_hw.c
+===================================================================
+--- linux-2.6.26.orig/drivers/net/wireless/hostap/hostap_hw.c 2008-10-17 18:13:21.000000000 +0200
++++ linux-2.6.26/drivers/net/wireless/hostap/hostap_hw.c 2008-10-17 18:15:31.443789719 +0200
@@ -54,6 +54,7 @@
#include "hostap.h"
#include "hostap_ap.h"
@@ -591,7 +1294,7 @@ index 13d5882..6f24d66 100644
/* #define final_version */
-@@ -1497,6 +1498,8 @@ static int prism2_hw_config(struct net_device *dev, int initial)
+@@ -1534,6 +1535,8 @@
if (local->hw_downloading)
return 1;
@@ -600,7 +1303,7 @@ index 13d5882..6f24d66 100644
if (prism2_hw_init(dev, initial)) {
return local->no_pri ? 0 : 1;
}
-@@ -2628,8 +2631,15 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id)
+@@ -2665,8 +2668,15 @@
int events = 0;
u16 ev;
@@ -616,12 +1319,12 @@ index 13d5882..6f24d66 100644
+ iface = netdev_priv(dev);
+ local = iface->local;
- prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0);
-
-diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
-index 3a874fc..df58aa3 100644
---- a/drivers/net/wireless/hostap/hostap_pci.c
-+++ b/drivers/net/wireless/hostap/hostap_pci.c
+ if(dev->base_addr == 0)
+ {
+Index: linux-2.6.26/drivers/net/wireless/hostap/hostap_pci.c
+===================================================================
+--- linux-2.6.26.orig/drivers/net/wireless/hostap/hostap_pci.c 2008-10-17 18:13:18.000000000 +0200
++++ linux-2.6.26/drivers/net/wireless/hostap/hostap_pci.c 2008-10-17 18:15:31.447790279 +0200
@@ -19,6 +19,7 @@
#include "hostap_wlan.h"
@@ -630,10 +1333,10 @@ index 3a874fc..df58aa3 100644
static char *dev_info = "hostap_pci";
-diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
-index cbf15d7..4475174 100644
---- a/drivers/net/wireless/hostap/hostap_plx.c
-+++ b/drivers/net/wireless/hostap/hostap_plx.c
+Index: linux-2.6.26/drivers/net/wireless/hostap/hostap_plx.c
+===================================================================
+--- linux-2.6.26.orig/drivers/net/wireless/hostap/hostap_plx.c 2008-10-17 18:13:18.000000000 +0200
++++ linux-2.6.26/drivers/net/wireless/hostap/hostap_plx.c 2008-10-17 18:15:31.451790719 +0200
@@ -21,7 +21,7 @@
#include <asm/io.h>
@@ -643,11 +1346,11 @@ index cbf15d7..4475174 100644
static char *dev_info = "hostap_plx";
-diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
-index c5b2a44..eecbe8c 100644
---- a/drivers/pcmcia/sa1100_generic.c
-+++ b/drivers/pcmcia/sa1100_generic.c
-@@ -81,13 +81,14 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
+Index: linux-2.6.26/drivers/pcmcia/sa1100_generic.c
+===================================================================
+--- linux-2.6.26.orig/drivers/pcmcia/sa1100_generic.c 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/drivers/pcmcia/sa1100_generic.c 2008-10-17 18:15:31.459789719 +0200
+@@ -81,13 +81,14 @@
return ret;
}
@@ -669,7 +1372,7 @@ index c5b2a44..eecbe8c 100644
};
/* sa11x0_pcmcia_init()
-@@ -100,7 +101,7 @@ static struct device_driver sa11x0_pcmcia_driver = {
+@@ -100,7 +101,7 @@
*/
static int __init sa11x0_pcmcia_init(void)
{
@@ -678,7 +1381,7 @@ index c5b2a44..eecbe8c 100644
}
/* sa11x0_pcmcia_exit()
-@@ -110,7 +111,7 @@ static int __init sa11x0_pcmcia_init(void)
+@@ -110,7 +111,7 @@
*/
static void __exit sa11x0_pcmcia_exit(void)
{
@@ -687,11 +1390,11 @@ index c5b2a44..eecbe8c 100644
}
MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
-diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
-index 66ec5d8..aba38d7 100644
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -123,6 +123,10 @@ config SPI_MPC52xx_PSC
+Index: linux-2.6.26/drivers/spi/Kconfig
+===================================================================
+--- linux-2.6.26.orig/drivers/spi/Kconfig 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/drivers/spi/Kconfig 2008-10-17 18:15:31.463790519 +0200
+@@ -123,6 +123,10 @@
This enables using the Freescale MPC52xx Programmable Serial
Controller in master SPI mode.
@@ -702,11 +1405,11 @@ index 66ec5d8..aba38d7 100644
config SPI_MPC83xx
tristate "Freescale MPC83xx/QUICC Engine SPI controller"
depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
-diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
-index 7fca043..b89992b 100644
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -28,6 +28,7 @@ obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
+Index: linux-2.6.26/drivers/spi/Makefile
+===================================================================
+--- linux-2.6.26.orig/drivers/spi/Makefile 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/drivers/spi/Makefile 2008-10-17 18:15:31.463790519 +0200
+@@ -28,6 +28,7 @@
obj-$(CONFIG_SPI_TXX9) += spi_txx9.o
obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o
obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
@@ -714,11 +1417,10 @@ index 7fca043..b89992b 100644
# ... add above this line ...
# SPI protocol drivers (device/link on bus)
-diff --git a/drivers/spi/locomo_spi.c b/drivers/spi/locomo_spi.c
-new file mode 100644
-index 0000000..d3a4bd9
---- /dev/null
-+++ b/drivers/spi/locomo_spi.c
+Index: linux-2.6.26/drivers/spi/locomo_spi.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.26/drivers/spi/locomo_spi.c 2008-10-17 18:15:31.471790439 +0200
@@ -0,0 +1,1097 @@
+#include <asm/io.h>
+#include <asm/irq.h>
@@ -1817,11 +2519,10 @@ index 0000000..d3a4bd9
+MODULE_AUTHOR("Thomas Kunze thommy@tabao.de");
+MODULE_DESCRIPTION("Collie mmc driver");
+MODULE_LICENSE("GPL");
-diff --git a/drivers/spi/locomo_spi.h b/drivers/spi/locomo_spi.h
-new file mode 100644
-index 0000000..7e1c0ce
---- /dev/null
-+++ b/drivers/spi/locomo_spi.h
+Index: linux-2.6.26/drivers/spi/locomo_spi.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.26/drivers/spi/locomo_spi.h 2008-10-17 18:15:31.471790439 +0200
@@ -0,0 +1,75 @@
+#include <asm/hardware/locomo.h>
+#ifndef __LOCOMO_SPI_H__
diff --git a/packages/kexecboot/linux-kexecboot-2.6.26/collie/defconfig b/packages/kexecboot/linux-kexecboot-2.6.26/collie/defconfig
index a65552fbbb..4434962a64 100644
--- a/packages/kexecboot/linux-kexecboot-2.6.26/collie/defconfig
+++ b/packages/kexecboot/linux-kexecboot-2.6.26/collie/defconfig
@@ -327,13 +327,8 @@ CONFIG_MTD_BLOCK=y
#
# RAM/ROM/Flash chip drivers
#
-CONFIG_MTD_CFI=y
+# CONFIG_MTD_CFI is not set
# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-# CONFIG_MTD_CFI_NOSWAP is not set
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -344,14 +339,10 @@ CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_XIP is not set
+CONFING_MTD_SHARP=y
#
# Mapping drivers for chip access
diff --git a/packages/kexecboot/linux-kexecboot_2.6.26.bb b/packages/kexecboot/linux-kexecboot_2.6.26.bb
index 6dec914cc6..7d000ff2e1 100644
--- a/packages/kexecboot/linux-kexecboot_2.6.26.bb
+++ b/packages/kexecboot/linux-kexecboot_2.6.26.bb
@@ -1,6 +1,6 @@
require linux-kexecboot.inc
-FILE_PR = "r4"
+FILE_PR = "r5"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_qemuarm = "-1"
DEFAULT_PREFERENCE_qemux86 = "-1"