Skip to content
Snippets Groups Projects
Commit 22ae77bc authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge git://git.infradead.org/mtd-2.6

* git://git.infradead.org/mtd-2.6: (53 commits)
  [MTD] struct device - replace bus_id with dev_name(), dev_set_name()
  [MTD] [NOR] Fixup for Numonyx M29W128 chips
  [MTD] mtdpart: Make ecc_stats more realistic.
  powerpc/85xx: TQM8548: Update DTS file for multi-chip support
  powerpc: NAND: FSL UPM: document new bindings
  [MTD] [NAND] FSL-UPM: Add wait flags to support board/chip specific delays
  [MTD] [NAND] FSL-UPM: add multi chip support
  [MTD] [NOR] Add device parent info to physmap_of
  [MTD] [NAND] Add support for NAND on the Socrates board
  [MTD] [NAND] Add support for 4KiB pages.
  [MTD] sysfs support should not depend on CONFIG_PROC_FS
  [MTD] [NAND] Add parent info for CAFÉ controller
  [MTD] support driver model updates
  [MTD] driver model updates (part 2)
  [MTD] driver model updates
  [MTD] [NAND] move gen_nand's probe function to .devinit.text
  [MTD] [MAPS] move sa1100 flash's probe function to .devinit.text
  [MTD] fix use after free in register_mtd_blktrans
  [MTD] [MAPS] Drop now unused sharpsl-flash map
  [MTD] ofpart: Check name property to determine partition nodes.
  ...

Manually fix trivial conflict in drivers/mtd/maps/Makefile
parents e379ec7c 30bbf140
No related merge requests found
Showing
with 418 additions and 13 deletions
...@@ -5,9 +5,21 @@ Required properties: ...@@ -5,9 +5,21 @@ Required properties:
- reg : should specify localbus chip select and size used for the chip. - reg : should specify localbus chip select and size used for the chip.
- fsl,upm-addr-offset : UPM pattern offset for the address latch. - fsl,upm-addr-offset : UPM pattern offset for the address latch.
- fsl,upm-cmd-offset : UPM pattern offset for the command latch. - fsl,upm-cmd-offset : UPM pattern offset for the command latch.
- gpios : may specify optional GPIO connected to the Ready-Not-Busy pin.
Example: Optional properties:
- fsl,upm-wait-flags : add chip-dependent short delays after running the
UPM pattern (0x1), after writing a data byte (0x2) or after
writing out a buffer (0x4).
- fsl,upm-addr-line-cs-offsets : address offsets for multi-chip support.
The corresponding address lines are used to select the chip.
- gpios : may specify optional GPIOs connected to the Ready-Not-Busy pins
(R/B#). For multi-chip devices, "n" GPIO definitions are required
according to the number of chips.
- chip-delay : chip dependent delay for transfering data from array to
read registers (tR). Required if property "gpios" is not used
(R/B# pins not connected).
Examples:
upm@1,0 { upm@1,0 {
compatible = "fsl,upm-nand"; compatible = "fsl,upm-nand";
...@@ -26,3 +38,26 @@ upm@1,0 { ...@@ -26,3 +38,26 @@ upm@1,0 {
}; };
}; };
}; };
upm@3,0 {
#address-cells = <0>;
#size-cells = <0>;
compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
reg = <3 0x0 0x800>;
fsl,upm-addr-offset = <0x10>;
fsl,upm-cmd-offset = <0x08>;
/* Multi-chip NAND device */
fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
fsl,upm-wait-flags = <0x5>;
chip-delay = <25>; // in micro-seconds
nand@0 {
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "fs";
reg = <0x00000000 0x10000000>;
};
};
};
/*
* mach-davinci/nand.h
*
* Copyright © 2006 Texas Instruments.
*
* Ported to 2.6.23 Copyright © 2008 by
* Sander Huijsen <Shuijsen@optelecom-nkf.com>
* Troy Kisky <troy.kisky@boundarydevices.com>
* Dirk Behme <Dirk.Behme@gmail.com>
*
* --------------------------------------------------------------------------
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ARCH_ARM_DAVINCI_NAND_H
#define __ARCH_ARM_DAVINCI_NAND_H
#include <linux/mtd/nand.h>
#define NRCSR_OFFSET 0x00
#define AWCCR_OFFSET 0x04
#define A1CR_OFFSET 0x10
#define NANDFCR_OFFSET 0x60
#define NANDFSR_OFFSET 0x64
#define NANDF1ECC_OFFSET 0x70
/* 4-bit ECC syndrome registers */
#define NAND_4BIT_ECC_LOAD_OFFSET 0xbc
#define NAND_4BIT_ECC1_OFFSET 0xc0
#define NAND_4BIT_ECC2_OFFSET 0xc4
#define NAND_4BIT_ECC3_OFFSET 0xc8
#define NAND_4BIT_ECC4_OFFSET 0xcc
#define NAND_ERR_ADD1_OFFSET 0xd0
#define NAND_ERR_ADD2_OFFSET 0xd4
#define NAND_ERR_ERRVAL1_OFFSET 0xd8
#define NAND_ERR_ERRVAL2_OFFSET 0xdc
/* NOTE: boards don't need to use these address bits
* for ALE/CLE unless they support booting from NAND.
* They're used unless platform data overrides them.
*/
#define MASK_ALE 0x08
#define MASK_CLE 0x10
struct davinci_nand_pdata { /* platform_data */
uint32_t mask_ale;
uint32_t mask_cle;
/* for packages using two chipselects */
uint32_t mask_chipsel;
/* board's default static partition info */
struct mtd_partition *parts;
unsigned nr_parts;
/* none == NAND_ECC_NONE (strongly *not* advised!!)
* soft == NAND_ECC_SOFT
* 1-bit == NAND_ECC_HW
* 4-bit == NAND_ECC_HW_SYNDROME (not on all chips)
*/
nand_ecc_modes_t ecc_mode;
/* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
unsigned options;
};
#endif /* __ARCH_ARM_DAVINCI_NAND_H */
...@@ -49,6 +49,9 @@ struct pxa3xx_nand_platform_data { ...@@ -49,6 +49,9 @@ struct pxa3xx_nand_platform_data {
*/ */
int enable_arbiter; int enable_arbiter;
/* allow platform code to keep OBM/bootloader defined NFC config */
int keep_config;
const struct mtd_partition *parts; const struct mtd_partition *parts;
unsigned int nr_parts; unsigned int nr_parts;
......
...@@ -337,7 +337,7 @@ int _access_ok(unsigned long addr, unsigned long size) ...@@ -337,7 +337,7 @@ int _access_ok(unsigned long addr, unsigned long size)
if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end) if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end)
return 1; return 1;
#ifdef CONFIG_ROMFS_MTD_FS #ifdef CONFIG_ROMFS_ON_MTD
/* For XIP, allow user space to use pointers within the ROMFS. */ /* For XIP, allow user space to use pointers within the ROMFS. */
if (addr >= memory_mtd_start && (addr + size) <= memory_mtd_end) if (addr >= memory_mtd_start && (addr + size) <= memory_mtd_end)
return 1; return 1;
......
/*
* 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.
*
* (C) Copyright TOSHIBA CORPORATION 2007
*/
#ifndef __ASM_TXX9_NDFMC_H
#define __ASM_TXX9_NDFMC_H
#define NDFMC_PLAT_FLAG_USE_BSPRT 0x01
#define NDFMC_PLAT_FLAG_NO_RSTR 0x02
#define NDFMC_PLAT_FLAG_HOLDADD 0x04
#define NDFMC_PLAT_FLAG_DUMMYWRITE 0x08
struct txx9ndfmc_platform_data {
unsigned int shift;
unsigned int gbus_clock;
unsigned int hold; /* hold time in nanosecond */
unsigned int spw; /* strobe pulse width in nanosecond */
unsigned int flags;
unsigned char ch_mask; /* available channel bitmask */
unsigned char wp_mask; /* write-protect bitmask */
unsigned char wide_mask; /* 16bit-nand bitmask */
};
void txx9_ndfmc_init(unsigned long baseaddr,
const struct txx9ndfmc_platform_data *plat_data);
#endif /* __ASM_TXX9_NDFMC_H */
...@@ -130,4 +130,13 @@ ...@@ -130,4 +130,13 @@
void rbtx4939_prom_init(void); void rbtx4939_prom_init(void);
void rbtx4939_irq_setup(void); void rbtx4939_irq_setup(void);
struct mtd_partition;
struct map_info;
struct rbtx4939_flash_data {
unsigned int width;
unsigned int nr_parts;
struct mtd_partition *parts;
void (*map_init)(struct map_info *map);
};
#endif /* __ASM_TXX9_RBTX4939_H */ #endif /* __ASM_TXX9_RBTX4939_H */
...@@ -291,6 +291,7 @@ int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot); ...@@ -291,6 +291,7 @@ int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot);
void tx4938_setup_pcierr_irq(void); void tx4938_setup_pcierr_irq(void);
void tx4938_irq_init(void); void tx4938_irq_init(void);
void tx4938_mtd_init(int ch); void tx4938_mtd_init(int ch);
void tx4938_ndfmc_init(unsigned int hold, unsigned int spw);
struct tx4938ide_platform_info { struct tx4938ide_platform_info {
/* /*
......
...@@ -542,5 +542,7 @@ int tx4939_irq(void); ...@@ -542,5 +542,7 @@ int tx4939_irq(void);
void tx4939_mtd_init(int ch); void tx4939_mtd_init(int ch);
void tx4939_ata_init(void); void tx4939_ata_init(void);
void tx4939_rtc_init(void); void tx4939_rtc_init(void);
void tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
unsigned char ch_mask, unsigned char wide_mask);
#endif /* __ASM_TXX9_TX4939_H */ #endif /* __ASM_TXX9_TX4939_H */
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <asm/txx9/generic.h> #include <asm/txx9/generic.h>
#include <asm/txx9/pci.h> #include <asm/txx9/pci.h>
#include <asm/txx9tmr.h> #include <asm/txx9tmr.h>
#include <asm/txx9/ndfmc.h>
#ifdef CONFIG_CPU_TX49XX #ifdef CONFIG_CPU_TX49XX
#include <asm/txx9/tx4938.h> #include <asm/txx9/tx4938.h>
#endif #endif
...@@ -691,6 +692,26 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr, ...@@ -691,6 +692,26 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr,
#endif #endif
} }
void __init txx9_ndfmc_init(unsigned long baseaddr,
const struct txx9ndfmc_platform_data *pdata)
{
#if defined(CONFIG_MTD_NAND_TXX9NDFMC) || \
defined(CONFIG_MTD_NAND_TXX9NDFMC_MODULE)
struct resource res = {
.start = baseaddr,
.end = baseaddr + 0x1000 - 1,
.flags = IORESOURCE_MEM,
};
struct platform_device *pdev = platform_device_alloc("txx9ndfmc", -1);
if (!pdev ||
platform_device_add_resources(pdev, &res, 1) ||
platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
platform_device_add(pdev))
platform_device_put(pdev);
#endif
}
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
static DEFINE_SPINLOCK(txx9_iocled_lock); static DEFINE_SPINLOCK(txx9_iocled_lock);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <asm/txx9tmr.h> #include <asm/txx9tmr.h>
#include <asm/txx9pio.h> #include <asm/txx9pio.h>
#include <asm/txx9/generic.h> #include <asm/txx9/generic.h>
#include <asm/txx9/ndfmc.h>
#include <asm/txx9/tx4938.h> #include <asm/txx9/tx4938.h>
static void __init tx4938_wdr_init(void) static void __init tx4938_wdr_init(void)
...@@ -382,6 +383,26 @@ void __init tx4938_ata_init(unsigned int irq, unsigned int shift, int tune) ...@@ -382,6 +383,26 @@ void __init tx4938_ata_init(unsigned int irq, unsigned int shift, int tune)
platform_device_put(pdev); platform_device_put(pdev);
} }
void __init tx4938_ndfmc_init(unsigned int hold, unsigned int spw)
{
struct txx9ndfmc_platform_data plat_data = {
.shift = 1,
.gbus_clock = txx9_gbus_clock,
.hold = hold,
.spw = spw,
.ch_mask = 1,
};
unsigned long baseaddr = TX4938_NDFMC_REG & 0xfffffffffULL;
#ifdef __BIG_ENDIAN
baseaddr += 4;
#endif
if ((__raw_readq(&tx4938_ccfgptr->pcfg) &
(TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL)) ==
TX4938_PCFG_NDF_SEL)
txx9_ndfmc_init(baseaddr, &plat_data);
}
static void __init tx4938_stop_unused_modules(void) static void __init tx4938_stop_unused_modules(void)
{ {
__u64 pcfg, rst = 0, ckd = 0; __u64 pcfg, rst = 0, ckd = 0;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <asm/txx9irq.h> #include <asm/txx9irq.h>
#include <asm/txx9tmr.h> #include <asm/txx9tmr.h>
#include <asm/txx9/generic.h> #include <asm/txx9/generic.h>
#include <asm/txx9/ndfmc.h>
#include <asm/txx9/tx4939.h> #include <asm/txx9/tx4939.h>
static void __init tx4939_wdr_init(void) static void __init tx4939_wdr_init(void)
...@@ -457,6 +458,22 @@ void __init tx4939_rtc_init(void) ...@@ -457,6 +458,22 @@ void __init tx4939_rtc_init(void)
platform_device_register(&rtc_dev); platform_device_register(&rtc_dev);
} }
void __init tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
unsigned char ch_mask, unsigned char wide_mask)
{
struct txx9ndfmc_platform_data plat_data = {
.shift = 1,
.gbus_clock = txx9_gbus_clock,
.hold = hold,
.spw = spw,
.flags = NDFMC_PLAT_FLAG_NO_RSTR | NDFMC_PLAT_FLAG_HOLDADD |
NDFMC_PLAT_FLAG_DUMMYWRITE,
.ch_mask = ch_mask,
.wide_mask = wide_mask,
};
txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
}
static void __init tx4939_stop_unused_modules(void) static void __init tx4939_stop_unused_modules(void)
{ {
__u64 pcfg, rst = 0, ckd = 0; __u64 pcfg, rst = 0, ckd = 0;
......
...@@ -352,6 +352,8 @@ static void __init rbtx4938_device_init(void) ...@@ -352,6 +352,8 @@ static void __init rbtx4938_device_init(void)
rbtx4938_ne_init(); rbtx4938_ne_init();
tx4938_wdt_init(); tx4938_wdt_init();
rbtx4938_mtd_init(); rbtx4938_mtd_init();
/* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
tx4938_ndfmc_init(10, 35);
tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1); tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1);
txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL); txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
} }
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/smc91x.h> #include <linux/smc91x.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/map.h>
#include <asm/reboot.h> #include <asm/reboot.h>
#include <asm/txx9/generic.h> #include <asm/txx9/generic.h>
#include <asm/txx9/pci.h> #include <asm/txx9/pci.h>
...@@ -282,6 +285,159 @@ static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val) ...@@ -282,6 +285,159 @@ static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
__rbtx4939_7segled_putc(pos, val); __rbtx4939_7segled_putc(pos, val);
} }
#if defined(CONFIG_MTD_RBTX4939) || defined(CONFIG_MTD_RBTX4939_MODULE)
/* special mapping for boot rom */
static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs)
{
u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
unsigned char shift;
if (bdipsw & 8) {
/* BOOT Mode: USER ROM1 / USER ROM2 */
shift = bdipsw & 3;
/* rotate A[23:22] */
return (ofs & ~0xc00000) | ((((ofs >> 22) + shift) & 3) << 22);
}
#ifdef __BIG_ENDIAN
if (bdipsw == 0)
/* BOOT Mode: Monitor ROM */
ofs ^= 0x400000; /* swap A[22] */
#endif
return ofs;
}
static map_word rbtx4939_flash_read16(struct map_info *map, unsigned long ofs)
{
map_word r;
ofs = rbtx4939_flash_fixup_ofs(ofs);
r.x[0] = __raw_readw(map->virt + ofs);
return r;
}
static void rbtx4939_flash_write16(struct map_info *map, const map_word datum,
unsigned long ofs)
{
ofs = rbtx4939_flash_fixup_ofs(ofs);
__raw_writew(datum.x[0], map->virt + ofs);
mb(); /* see inline_map_write() in mtd/map.h */
}
static void rbtx4939_flash_copy_from(struct map_info *map, void *to,
unsigned long from, ssize_t len)
{
u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
unsigned char shift;
ssize_t curlen;
from += (unsigned long)map->virt;
if (bdipsw & 8) {
/* BOOT Mode: USER ROM1 / USER ROM2 */
shift = bdipsw & 3;
while (len) {
curlen = min_t(unsigned long, len,
0x400000 - (from & (0x400000 - 1)));
memcpy(to,
(void *)((from & ~0xc00000) |
((((from >> 22) + shift) & 3) << 22)),
curlen);
len -= curlen;
from += curlen;
to += curlen;
}
return;
}
#ifdef __BIG_ENDIAN
if (bdipsw == 0) {
/* BOOT Mode: Monitor ROM */
while (len) {
curlen = min_t(unsigned long, len,
0x400000 - (from & (0x400000 - 1)));
memcpy(to, (void *)(from ^ 0x400000), curlen);
len -= curlen;
from += curlen;
to += curlen;
}
return;
}
#endif
memcpy(to, (void *)from, len);
}
static void rbtx4939_flash_map_init(struct map_info *map)
{
map->read = rbtx4939_flash_read16;
map->write = rbtx4939_flash_write16;
map->copy_from = rbtx4939_flash_copy_from;
}
static void __init rbtx4939_mtd_init(void)
{
static struct {
struct platform_device dev;
struct resource res;
struct rbtx4939_flash_data data;
} pdevs[4];
int i;
static char names[4][8];
static struct mtd_partition parts[4];
struct rbtx4939_flash_data *boot_pdata = &pdevs[0].data;
u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
if (bdipsw & 8) {
/* BOOT Mode: USER ROM1 / USER ROM2 */
boot_pdata->nr_parts = 4;
for (i = 0; i < boot_pdata->nr_parts; i++) {
sprintf(names[i], "img%d", 4 - i);
parts[i].name = names[i];
parts[i].size = 0x400000;
parts[i].offset = MTDPART_OFS_NXTBLK;
}
} else if (bdipsw == 0) {
/* BOOT Mode: Monitor ROM */
boot_pdata->nr_parts = 2;
strcpy(names[0], "big");
strcpy(names[1], "little");
for (i = 0; i < boot_pdata->nr_parts; i++) {
parts[i].name = names[i];
parts[i].size = 0x400000;
parts[i].offset = MTDPART_OFS_NXTBLK;
}
} else {
/* BOOT Mode: ROM Emulator */
boot_pdata->nr_parts = 2;
parts[0].name = "boot";
parts[0].offset = 0xc00000;
parts[0].size = 0x400000;
parts[1].name = "user";
parts[1].offset = 0;
parts[1].size = 0xc00000;
}
boot_pdata->parts = parts;
boot_pdata->map_init = rbtx4939_flash_map_init;
for (i = 0; i < ARRAY_SIZE(pdevs); i++) {
struct resource *r = &pdevs[i].res;
struct platform_device *dev = &pdevs[i].dev;
r->start = 0x1f000000 - i * 0x1000000;
r->end = r->start + 0x1000000 - 1;
r->flags = IORESOURCE_MEM;
pdevs[i].data.width = 2;
dev->num_resources = 1;
dev->resource = r;
dev->id = i;
dev->name = "rbtx4939-flash";
dev->dev.platform_data = &pdevs[i].data;
platform_device_register(dev);
}
}
#else
static void __init rbtx4939_mtd_init(void)
{
}
#endif
static void __init rbtx4939_arch_init(void) static void __init rbtx4939_arch_init(void)
{ {
rbtx4939_pci_setup(); rbtx4939_pci_setup();
...@@ -333,6 +489,11 @@ static void __init rbtx4939_device_init(void) ...@@ -333,6 +489,11 @@ static void __init rbtx4939_device_init(void)
platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) || platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) ||
platform_device_add(pdev)) platform_device_add(pdev))
platform_device_put(pdev); platform_device_put(pdev);
rbtx4939_mtd_init();
/* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
tx4939_ndfmc_init(10, 35,
(1 << 1) | (1 << 2),
(1 << 2)); /* ch1:8bit, ch2:16bit */
rbtx4939_led_setup(); rbtx4939_led_setup();
tx4939_wdt_init(); tx4939_wdt_init();
tx4939_ata_init(); tx4939_ata_init();
......
...@@ -397,10 +397,13 @@ ...@@ -397,10 +397,13 @@
upm@3,0 { upm@3,0 {
#address-cells = <0>; #address-cells = <0>;
#size-cells = <0>; #size-cells = <0>;
compatible = "fsl,upm-nand"; compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
reg = <3 0x0 0x800>; reg = <3 0x0 0x800>;
fsl,upm-addr-offset = <0x10>; fsl,upm-addr-offset = <0x10>;
fsl,upm-cmd-offset = <0x08>; fsl,upm-cmd-offset = <0x08>;
/* Micron MT29F8G08FAB multi-chip device */
fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
fsl,upm-wait-flags = <0x5>;
chip-delay = <25>; // in micro-seconds chip-delay = <25>; // in micro-seconds
nand@0 { nand@0 {
...@@ -409,7 +412,7 @@ ...@@ -409,7 +412,7 @@
partition@0 { partition@0 {
label = "fs"; label = "fs";
reg = <0x00000000 0x01000000>; reg = <0x00000000 0x10000000>;
}; };
}; };
}; };
......
...@@ -397,10 +397,13 @@ ...@@ -397,10 +397,13 @@
upm@3,0 { upm@3,0 {
#address-cells = <0>; #address-cells = <0>;
#size-cells = <0>; #size-cells = <0>;
compatible = "fsl,upm-nand"; compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
reg = <3 0x0 0x800>; reg = <3 0x0 0x800>;
fsl,upm-addr-offset = <0x10>; fsl,upm-addr-offset = <0x10>;
fsl,upm-cmd-offset = <0x08>; fsl,upm-cmd-offset = <0x08>;
/* Micron MT29F8G08FAB multi-chip device */
fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
fsl,upm-wait-flags = <0x5>;
chip-delay = <25>; // in micro-seconds chip-delay = <25>; // in micro-seconds
nand@0 { nand@0 {
...@@ -409,7 +412,7 @@ ...@@ -409,7 +412,7 @@
partition@0 { partition@0 {
label = "fs"; label = "fs";
reg = <0x00000000 0x01000000>; reg = <0x00000000 0x10000000>;
}; };
}; };
}; };
......
...@@ -150,7 +150,7 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar) ...@@ -150,7 +150,7 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
spin_lock_irqsave(&fsl_lbc_lock, flags); spin_lock_irqsave(&fsl_lbc_lock, flags);
out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width)); out_be32(&fsl_lbc_regs->mar, mar);
switch (upm->width) { switch (upm->width) {
case 8: case 8:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Core functionality. # Core functionality.
obj-$(CONFIG_MTD) += mtd.o obj-$(CONFIG_MTD) += mtd.o
mtd-y := mtdcore.o mtdsuper.o mtd-y := mtdcore.o mtdsuper.o mtdbdi.o
mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
......
...@@ -44,8 +44,6 @@ struct ar7_bin_rec { ...@@ -44,8 +44,6 @@ struct ar7_bin_rec {
unsigned int address; unsigned int address;
}; };
static struct mtd_partition ar7_parts[AR7_PARTS];
static int create_mtd_partitions(struct mtd_info *master, static int create_mtd_partitions(struct mtd_info *master,
struct mtd_partition **pparts, struct mtd_partition **pparts,
unsigned long origin) unsigned long origin)
...@@ -57,7 +55,11 @@ static int create_mtd_partitions(struct mtd_info *master, ...@@ -57,7 +55,11 @@ static int create_mtd_partitions(struct mtd_info *master,
unsigned int root_offset = ROOT_OFFSET; unsigned int root_offset = ROOT_OFFSET;
int retries = 10; int retries = 10;
struct mtd_partition *ar7_parts;
ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL);
if (!ar7_parts)
return -ENOMEM;
ar7_parts[0].name = "loader"; ar7_parts[0].name = "loader";
ar7_parts[0].offset = 0; ar7_parts[0].offset = 0;
ar7_parts[0].size = master->erasesize; ar7_parts[0].size = master->erasesize;
......
...@@ -1236,10 +1236,14 @@ static int inval_cache_and_wait_for_operation( ...@@ -1236,10 +1236,14 @@ static int inval_cache_and_wait_for_operation(
remove_wait_queue(&chip->wq, &wait); remove_wait_queue(&chip->wq, &wait);
spin_lock(chip->mutex); spin_lock(chip->mutex);
} }
if (chip->erase_suspended || chip->write_suspended) { if (chip->erase_suspended && chip_state == FL_ERASING) {
/* Suspend has occured while sleep: reset timeout */ /* Erase suspend occured while sleep: reset timeout */
timeo = reset_timeo; timeo = reset_timeo;
chip->erase_suspended = 0; chip->erase_suspended = 0;
}
if (chip->write_suspended && chip_state == FL_WRITING) {
/* Write suspend occured while sleep: reset timeout */
timeo = reset_timeo;
chip->write_suspended = 0; chip->write_suspended = 0;
} }
} }
......
...@@ -282,6 +282,16 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param) ...@@ -282,6 +282,16 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
} }
} }
static void fixup_M29W128G_write_buffer(struct mtd_info *mtd, void *param)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
if (cfi->cfiq->BufWriteTimeoutTyp) {
pr_warning("Don't use write buffer on ST flash M29W128G\n");
cfi->cfiq->BufWriteTimeoutTyp = 0;
}
}
static struct cfi_fixup cfi_fixup_table[] = { static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
#ifdef AMD_BOOTLOC_BUG #ifdef AMD_BOOTLOC_BUG
...@@ -298,6 +308,7 @@ static struct cfi_fixup cfi_fixup_table[] = { ...@@ -298,6 +308,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, }, { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
{ CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, }, { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
{ CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, }, { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
{ CFI_MFR_ST, 0x227E, fixup_M29W128G_write_buffer, NULL, },
#if !FORCE_WORD_WRITE #if !FORCE_WORD_WRITE
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
#endif #endif
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment