From 958429dd9f7b355a6e8358265ca0f056839b729c Mon Sep 17 00:00:00 2001 From: Thomas Kunze Date: Sat, 18 Oct 2008 02:04:35 +0200 Subject: linux-kexecboot: use hacked sharp-flash driver --- .../kexecboot/linux-kexecboot-2.6.26/collie.patch | 883 ++++++++++++++++++--- .../linux-kexecboot-2.6.26/collie/defconfig | 13 +- packages/kexecboot/linux-kexecboot_2.6.26.bb | 2 +- 3 files changed, 795 insertions(+), 103 deletions(-) (limited to 'packages/kexecboot') 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 +#include +#include ++#include + +#include -+#include +#include +#include + @@ -519,10 +531,10 @@ index 0000000..ddde5fc +MODULE_AUTHOR("Russell King "); +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 ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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<chipshift)) ++ thislen = (1<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<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<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 \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 "); ++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 @@ -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 "); -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 +#include @@ -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 +#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" -- cgit 1.2.3-korg