diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-12-09 13:30:15 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-12-09 13:30:15 +1100 |
commit | eb345f50f2ba68086b96fef4be4220ba565c0612 (patch) | |
tree | 8a2a6351fbdb9bdb1c386957ba0df76ad9ee13dd /drivers | |
parent | fdc0070a0a71d47dbbc00bf25fcf15c41eaae352 (diff) | |
parent | 4ccb3b4497ce01fab4933704fe21581e30fda1a5 (diff) |
Merge remote branch 'mtd/master'
Diffstat (limited to 'drivers')
31 files changed, 307 insertions, 258 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 1e2cbf5d9aa1..77414702cb00 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -53,9 +53,10 @@ config MTD_PARTITIONS devices. Partitioning on NFTL 'devices' is a different - that's the 'normal' form of partitioning used on a block device. +if MTD_PARTITIONS + config MTD_REDBOOT_PARTS tristate "RedBoot partition table parsing" - depends on MTD_PARTITIONS ---help--- RedBoot is a ROM monitor and bootloader which deals with multiple 'images' in flash devices by putting a table one of the erase @@ -72,9 +73,10 @@ config MTD_REDBOOT_PARTS SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for example. +if MTD_REDBOOT_PARTS + config MTD_REDBOOT_DIRECTORY_BLOCK int "Location of RedBoot partition table" - depends on MTD_REDBOOT_PARTS default "-1" ---help--- This option is the Linux counterpart to the @@ -91,18 +93,18 @@ config MTD_REDBOOT_DIRECTORY_BLOCK config MTD_REDBOOT_PARTS_UNALLOCATED bool "Include unallocated flash regions" - depends on MTD_REDBOOT_PARTS help If you need to register each unallocated flash region as a MTD 'partition', enable this option. config MTD_REDBOOT_PARTS_READONLY bool "Force read-only for RedBoot system images" - depends on MTD_REDBOOT_PARTS help If you need to force read-only for 'RedBoot', 'RedBoot Config' and 'FIS directory' images, enable this option. +endif # MTD_REDBOOT_PARTS + config MTD_CMDLINE_PARTS bool "Command line partition table parsing" depends on MTD_PARTITIONS = "y" && MTD = "y" @@ -142,7 +144,7 @@ config MTD_CMDLINE_PARTS config MTD_AFS_PARTS tristate "ARM Firmware Suite partition parsing" - depends on ARM && MTD_PARTITIONS + depends on ARM ---help--- The ARM Firmware Suite allows the user to divide flash devices into multiple 'images'. Each such image has a header containing its name @@ -158,8 +160,8 @@ config MTD_AFS_PARTS example. config MTD_OF_PARTS - tristate "Flash partition map based on OF description" - depends on (MICROBLAZE || PPC_OF) && MTD_PARTITIONS + def_bool y + depends on OF help This provides a partition parsing function which derives the partition map from the children of the flash node, @@ -167,10 +169,11 @@ config MTD_OF_PARTS config MTD_AR7_PARTS tristate "TI AR7 partitioning support" - depends on MTD_PARTITIONS ---help--- TI AR7 partitioning support +endif # MTD_PARTITIONS + comment "User Modules And Translation Layers" config MTD_CHAR diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 760abc533395..d4e7f25b1ebb 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -6,13 +6,13 @@ obj-$(CONFIG_MTD) += mtd.o mtd-y := mtdcore.o mtdsuper.o mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o +mtd-$(CONFIG_MTD_OF_PARTS) += ofpart.o obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o obj-$(CONFIG_MTD_AFS_PARTS) += afs.o obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o -obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o # 'Users' - code which presents functionality to userspace. obj-$(CONFIG_MTD_CHAR) += mtdchar.o diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index ad9268b44416..44cbfc093ecc 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -162,7 +162,7 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp) #endif /* Atmel chips don't use the same PRI format as Intel chips */ -static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) +static void fixup_convert_atmel_pri(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -202,7 +202,7 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) cfi->cfiq->BufWriteTimeoutMax = 0; } -static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param) +static void fixup_at49bv640dx_lock(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -214,7 +214,7 @@ static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param) #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ -static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) +static void fixup_intel_strataflash(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -227,7 +227,7 @@ static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) #endif #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND -static void fixup_no_write_suspend(struct mtd_info *mtd, void* param) +static void fixup_no_write_suspend(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -240,7 +240,7 @@ static void fixup_no_write_suspend(struct mtd_info *mtd, void* param) } #endif -static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param) +static void fixup_st_m28w320ct(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -249,7 +249,7 @@ static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param) cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ } -static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param) +static void fixup_st_m28w320cb(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -259,7 +259,7 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param) (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; }; -static void fixup_use_point(struct mtd_info *mtd, void *param) +static void fixup_use_point(struct mtd_info *mtd) { struct map_info *map = mtd->priv; if (!mtd->point && map_is_linear(map)) { @@ -268,7 +268,7 @@ static void fixup_use_point(struct mtd_info *mtd, void *param) } } -static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) +static void fixup_use_write_buffers(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -282,7 +282,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) /* * Some chips power-up with all sectors locked by default. */ -static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param) +static void fixup_unlock_powerup_lock(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -295,31 +295,31 @@ static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param) } static struct cfi_fixup cfi_fixup_table[] = { - { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, - { CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock, NULL }, - { CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock, NULL }, + { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri }, + { CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock }, + { CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock }, #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE - { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, + { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash }, #endif #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND - { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, + { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend }, #endif #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 }, #endif - { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL }, - { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL }, - { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, }, - { 0, 0, NULL, NULL } + { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct }, + { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb }, + { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock }, + { 0, 0, NULL } }; static struct cfi_fixup jedec_fixup_table[] = { - { CFI_MFR_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, - { 0, 0, NULL, NULL } + { CFI_MFR_INTEL, I82802AB, fixup_use_fwh_lock }, + { CFI_MFR_INTEL, I82802AC, fixup_use_fwh_lock }, + { CFI_MFR_ST, M50LPW080, fixup_use_fwh_lock }, + { CFI_MFR_ST, M50FLW080A, fixup_use_fwh_lock }, + { CFI_MFR_ST, M50FLW080B, fixup_use_fwh_lock }, + { 0, 0, NULL } }; static struct cfi_fixup fixup_table[] = { /* The CFI vendor ids and the JEDEC vendor IDs appear @@ -327,8 +327,8 @@ static struct cfi_fixup fixup_table[] = { * well. This table is to pick all cases where * we know that is the case. */ - { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point, NULL }, - { 0, 0, NULL, NULL } + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point }, + { 0, 0, NULL } }; static void cfi_fixup_major_minor(struct cfi_private *cfi, diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 3b8e32d87977..9d68ab919f31 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -134,7 +134,7 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp) #ifdef AMD_BOOTLOC_BUG /* Wheee. Bring me the head of someone at AMD. */ -static void fixup_amd_bootblock(struct mtd_info *mtd, void* param) +static void fixup_amd_bootblock(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -186,7 +186,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd, void* param) } #endif -static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) +static void fixup_use_write_buffers(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -197,7 +197,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) } /* Atmel chips don't use the same PRI format as AMD chips */ -static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) +static void fixup_convert_atmel_pri(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -228,14 +228,14 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) cfi->cfiq->BufWriteTimeoutMax = 0; } -static void fixup_use_secsi(struct mtd_info *mtd, void *param) +static void fixup_use_secsi(struct mtd_info *mtd) { /* Setup for chips with a secsi area */ mtd->read_user_prot_reg = cfi_amdstd_secsi_read; mtd->read_fact_prot_reg = cfi_amdstd_secsi_read; } -static void fixup_use_erase_chip(struct mtd_info *mtd, void *param) +static void fixup_use_erase_chip(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -250,7 +250,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param) * Some Atmel chips (e.g. the AT49BV6416) power-up with all sectors * locked by default. */ -static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param) +static void fixup_use_atmel_lock(struct mtd_info *mtd) { mtd->lock = cfi_atmel_lock; mtd->unlock = cfi_atmel_unlock; @@ -271,7 +271,7 @@ static void fixup_old_sst_eraseregion(struct mtd_info *mtd) cfi->cfiq->NumEraseRegions = 1; } -static void fixup_sst39vf(struct mtd_info *mtd, void *param) +static void fixup_sst39vf(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -282,7 +282,7 @@ static void fixup_sst39vf(struct mtd_info *mtd, void *param) cfi->addr_unlock2 = 0x2AAA; } -static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param) +static void fixup_sst39vf_rev_b(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -295,12 +295,12 @@ static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param) cfi->sector_erase_cmd = CMD(0x50); } -static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd, void *param) +static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; - fixup_sst39vf_rev_b(mtd, param); + fixup_sst39vf_rev_b(mtd); /* * CFI reports 1024 sectors (0x03ff+1) of 64KBytes (0x0100*256) where @@ -310,7 +310,7 @@ static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd, void *param) pr_warning("%s: Bad 38VF640x CFI data; adjusting sector size from 64 to 8KiB\n", mtd->name); } -static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param) +static void fixup_s29gl064n_sectors(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -321,7 +321,7 @@ static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param) } } -static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param) +static void fixup_s29gl032n_sectors(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -334,47 +334,47 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param) /* Used to fix CFI-Tables of chips without Extended Query Tables */ static struct cfi_fixup cfi_nopri_fixup_table[] = { - { CFI_MFR_SST, 0x234A, fixup_sst39vf, NULL, }, /* SST39VF1602 */ - { CFI_MFR_SST, 0x234B, fixup_sst39vf, NULL, }, /* SST39VF1601 */ - { CFI_MFR_SST, 0x235A, fixup_sst39vf, NULL, }, /* SST39VF3202 */ - { CFI_MFR_SST, 0x235B, fixup_sst39vf, NULL, }, /* SST39VF3201 */ - { CFI_MFR_SST, 0x235C, fixup_sst39vf_rev_b, NULL, }, /* SST39VF3202B */ - { CFI_MFR_SST, 0x235D, fixup_sst39vf_rev_b, NULL, }, /* SST39VF3201B */ - { CFI_MFR_SST, 0x236C, fixup_sst39vf_rev_b, NULL, }, /* SST39VF6402B */ - { CFI_MFR_SST, 0x236D, fixup_sst39vf_rev_b, NULL, }, /* SST39VF6401B */ - { 0, 0, NULL, NULL } + { CFI_MFR_SST, 0x234a, fixup_sst39vf }, /* SST39VF1602 */ + { CFI_MFR_SST, 0x234b, fixup_sst39vf }, /* SST39VF1601 */ + { CFI_MFR_SST, 0x235a, fixup_sst39vf }, /* SST39VF3202 */ + { CFI_MFR_SST, 0x235b, fixup_sst39vf }, /* SST39VF3201 */ + { CFI_MFR_SST, 0x235c, fixup_sst39vf_rev_b }, /* SST39VF3202B */ + { CFI_MFR_SST, 0x235d, fixup_sst39vf_rev_b }, /* SST39VF3201B */ + { CFI_MFR_SST, 0x236c, fixup_sst39vf_rev_b }, /* SST39VF6402B */ + { CFI_MFR_SST, 0x236d, fixup_sst39vf_rev_b }, /* SST39VF6401B */ + { 0, 0, NULL } }; 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 }, #ifdef AMD_BOOTLOC_BUG - { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, - { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock, NULL }, + { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock }, + { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock }, #endif - { CFI_MFR_AMD, 0x0050, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x0053, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x0055, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x0056, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x005C, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x005F, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors, NULL, }, - { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, }, - { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, }, - { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, }, - { CFI_MFR_SST, 0x536A, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6402 */ - { CFI_MFR_SST, 0x536B, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6401 */ - { CFI_MFR_SST, 0x536C, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6404 */ - { CFI_MFR_SST, 0x536D, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6403 */ + { CFI_MFR_AMD, 0x0050, fixup_use_secsi }, + { CFI_MFR_AMD, 0x0053, fixup_use_secsi }, + { CFI_MFR_AMD, 0x0055, fixup_use_secsi }, + { CFI_MFR_AMD, 0x0056, fixup_use_secsi }, + { CFI_MFR_AMD, 0x005C, fixup_use_secsi }, + { CFI_MFR_AMD, 0x005F, fixup_use_secsi }, + { CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors }, + { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors }, + { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors }, + { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors }, + { CFI_MFR_SST, 0x536a, fixup_sst38vf640x_sectorsize }, /* SST38VF6402 */ + { CFI_MFR_SST, 0x536b, fixup_sst38vf640x_sectorsize }, /* SST38VF6401 */ + { CFI_MFR_SST, 0x536c, fixup_sst38vf640x_sectorsize }, /* SST38VF6404 */ + { CFI_MFR_SST, 0x536d, fixup_sst38vf640x_sectorsize }, /* SST38VF6403 */ #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 }, #endif - { 0, 0, NULL, NULL } + { 0, 0, NULL } }; static struct cfi_fixup jedec_fixup_table[] = { - { CFI_MFR_SST, SST49LF004B, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_SST, SST49LF040B, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_SST, SST49LF008A, fixup_use_fwh_lock, NULL, }, - { 0, 0, NULL, NULL } + { CFI_MFR_SST, SST49LF004B, fixup_use_fwh_lock }, + { CFI_MFR_SST, SST49LF040B, fixup_use_fwh_lock }, + { CFI_MFR_SST, SST49LF008A, fixup_use_fwh_lock }, + { 0, 0, NULL } }; static struct cfi_fixup fixup_table[] = { @@ -383,9 +383,9 @@ static struct cfi_fixup fixup_table[] = { * well. This table is to pick all cases where * we know that is the case. */ - { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL }, - { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock, NULL }, - { 0, 0, NULL, NULL } + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip }, + { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock }, + { 0, 0, NULL } }; diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 360525c637d2..6ae3d111e1e7 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c @@ -156,7 +156,7 @@ void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup *fixups) for (f=fixups; f->fixup; f++) { if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) && ((f->id == CFI_ID_ANY) || (f->id == cfi->id))) { - f->fixup(mtd, f->param); + f->fixup(mtd); } } } diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h index d18064977192..5e3cc80128aa 100644 --- a/drivers/mtd/chips/fwh_lock.h +++ b/drivers/mtd/chips/fwh_lock.h @@ -98,7 +98,7 @@ static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, uint64_t len) return ret; } -static void fixup_use_fwh_lock(struct mtd_info *mtd, void *param) +static void fixup_use_fwh_lock(struct mtd_info *mtd) { printk(KERN_NOTICE "using fwh lock/unlock method\n"); /* Setup for the chips with the fwh lock method */ diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index bf5a002209bd..eabe5fb071c6 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -51,6 +51,10 @@ #define OPCODE_WRDI 0x04 /* Write disable */ #define OPCODE_AAI_WP 0xad /* Auto address increment word program */ +/* Used for Macronix flashes only. */ +#define OPCODE_EN4B 0xb7 /* Enter 4-byte mode */ +#define OPCODE_EX4B 0xe9 /* Exit 4-byte mode */ + /* Status Register bits. */ #define SR_WIP 1 /* Write in progress */ #define SR_WEL 2 /* Write enable latch */ @@ -62,7 +66,7 @@ /* Define max times to check status register before we give up. */ #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ -#define MAX_CMD_SIZE 4 +#define MAX_CMD_SIZE 5 #ifdef CONFIG_M25PXX_USE_FAST_READ #define OPCODE_READ OPCODE_FAST_READ @@ -152,6 +156,16 @@ static inline int write_disable(struct m25p *flash) } /* + * Enable/disable 4-byte addressing mode. + */ +static inline int set_4byte(struct m25p *flash, int enable) +{ + u8 code = enable ? OPCODE_EN4B : OPCODE_EX4B; + + return spi_write_then_read(flash->spi, &code, 1, NULL, 0); +} + +/* * Service routine to read status register until ready, or timeout occurs. * Returns non-zero if error. */ @@ -207,6 +221,7 @@ static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd) cmd[1] = addr >> (flash->addr_width * 8 - 8); cmd[2] = addr >> (flash->addr_width * 8 - 16); cmd[3] = addr >> (flash->addr_width * 8 - 24); + cmd[4] = addr >> (flash->addr_width * 8 - 32); } static int m25p_cmdsz(struct m25p *flash) @@ -607,7 +622,6 @@ struct flash_info { .sector_size = (_sector_size), \ .n_sectors = (_n_sectors), \ .page_size = 256, \ - .addr_width = 3, \ .flags = (_flags), \ }) @@ -653,6 +667,8 @@ static const struct spi_device_id m25p_ids[] = { { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, + { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, + { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, /* Spansion -- single (large) sector size only, at least * for the chips listed here (without boot sectors). @@ -764,6 +780,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) return &m25p_ids[tmp]; } } + dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec); return ERR_PTR(-ENODEV); } @@ -883,7 +900,17 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.dev.parent = &spi->dev; flash->page_size = info->page_size; - flash->addr_width = info->addr_width; + + if (info->addr_width) + flash->addr_width = info->addr_width; + else { + /* enable 4-byte addressing if the device exceeds 16MiB */ + if (flash->mtd.size > 0x1000000) { + flash->addr_width = 4; + set_4byte(flash, 1); + } else + flash->addr_width = 3; + } dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name, (long long)flash->mtd.size >> 10); diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 684247a8a5ed..c163e619abc9 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -335,7 +335,7 @@ out: return ret; } -static struct flash_info *__init sst25l_match_device(struct spi_device *spi) +static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi) { struct flash_info *flash_info = NULL; struct spi_message m; @@ -375,7 +375,7 @@ static struct flash_info *__init sst25l_match_device(struct spi_device *spi) return flash_info; } -static int __init sst25l_probe(struct spi_device *spi) +static int __devinit sst25l_probe(struct spi_device *spi) { struct flash_info *flash_info; struct sst25l_flash *flash; diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index 19fe92db0c46..77d64ce19e9f 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c @@ -149,11 +149,8 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, if (request_resource(&iomem_resource, &window->rsrc)) { window->rsrc.parent = NULL; printk(KERN_ERR MOD_NAME - " %s(): Unable to register resource" - " 0x%.16llx-0x%.16llx - kernel bug?\n", - __func__, - (unsigned long long)window->rsrc.start, - (unsigned long long)window->rsrc.end); + " %s(): Unable to register resource %pR - kernel bug?\n", + __func__, &window->rsrc); } diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c index d175c120ee84..1f3049590d9e 100644 --- a/drivers/mtd/maps/bcm963xx-flash.c +++ b/drivers/mtd/maps/bcm963xx-flash.c @@ -196,10 +196,15 @@ static int bcm963xx_probe(struct platform_device *pdev) bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map); if (!bcm963xx_mtd_info) { dev_err(&pdev->dev, "failed to probe using CFI\n"); + bcm963xx_mtd_info = do_map_probe("jedec_probe", &bcm963xx_map); + if (bcm963xx_mtd_info) + goto probe_ok; + dev_err(&pdev->dev, "failed to probe using JEDEC\n"); err = -EIO; goto err_probe; } +probe_ok: bcm963xx_mtd_info->owner = THIS_MODULE; /* This is mutually exclusive */ diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index ddb462bea9b5..5fdb7b26cea3 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c @@ -178,11 +178,8 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev, if (request_resource(&iomem_resource, &window->rsrc)) { window->rsrc.parent = NULL; printk(KERN_ERR MOD_NAME - " %s(): Unable to register resource" - " 0x%.016llx-0x%.016llx - kernel bug?\n", - __func__, - (unsigned long long)window->rsrc.start, - (unsigned long long)window->rsrc.end); + " %s(): Unable to register resource %pR - kernel bug?\n", + __func__, &window->rsrc); } diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c index d12c93dc1aad..4feb7507ab7c 100644 --- a/drivers/mtd/maps/esb2rom.c +++ b/drivers/mtd/maps/esb2rom.c @@ -242,12 +242,9 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev, window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; if (request_resource(&iomem_resource, &window->rsrc)) { window->rsrc.parent = NULL; - printk(KERN_DEBUG MOD_NAME - ": %s(): Unable to register resource" - " 0x%.08llx-0x%.08llx - kernel bug?\n", - __func__, - (unsigned long long)window->rsrc.start, - (unsigned long long)window->rsrc.end); + printk(KERN_DEBUG MOD_NAME ": " + "%s(): Unable to register resource %pR - kernel bug?\n", + __func__, &window->rsrc); } /* Map the firmware hub into my address space. */ diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c index f102bf243a74..1337a4191a0c 100644 --- a/drivers/mtd/maps/ichxrom.c +++ b/drivers/mtd/maps/ichxrom.c @@ -175,12 +175,9 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev, window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; if (request_resource(&iomem_resource, &window->rsrc)) { window->rsrc.parent = NULL; - printk(KERN_DEBUG MOD_NAME - ": %s(): Unable to register resource" - " 0x%.16llx-0x%.16llx - kernel bug?\n", - __func__, - (unsigned long long)window->rsrc.start, - (unsigned long long)window->rsrc.end); + printk(KERN_DEBUG MOD_NAME ": " + "%s(): Unable to register resource %pR - kernel bug?\n", + __func__, &window->rsrc); } /* Map the firmware hub into my address space. */ diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 9861814aa027..8506578e6a35 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -274,9 +274,7 @@ static int __devinit of_flash_probe(struct platform_device *dev, continue; } - dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n", - (unsigned long long)res.start, - (unsigned long long)res.end); + dev_dbg(&dev->dev, "of_flash device: %pR\n", &res); err = -EBUSY; res_size = resource_size(&res); diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c index b5391ebb736e..027e628a4f1d 100644 --- a/drivers/mtd/maps/scx200_docflash.c +++ b/drivers/mtd/maps/scx200_docflash.c @@ -166,9 +166,8 @@ static int __init init_scx200_docflash(void) outl(pmr, scx200_cb_base + SCx200_PMR); } - printk(KERN_INFO NAME ": DOCCS mapped at 0x%llx-0x%llx, width %d\n", - (unsigned long long)docmem.start, - (unsigned long long)docmem.end, width); + printk(KERN_INFO NAME ": DOCCS mapped at %pR, width %d\n", + &docmem, width); scx200_docflash_map.size = size; if (width == 8) diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c index 60146984f4be..c08e140d40ed 100644 --- a/drivers/mtd/maps/tqm8xxl.c +++ b/drivers/mtd/maps/tqm8xxl.c @@ -139,7 +139,7 @@ static int __init init_tqm_mtd(void) goto error_mem; } - map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL); + map_banks[idx]->name = kmalloc(16, GFP_KERNEL); if (!map_banks[idx]->name) { ret = -ENOMEM; diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 4759d827e8c7..16de17b5b829 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -522,10 +522,6 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - /* Only master mtd device must be used to control partitions */ - if (!mtd_is_master(mtd)) - return -EINVAL; - if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg))) return -EFAULT; @@ -535,6 +531,10 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd, switch (a.op) { case BLKPG_ADD_PARTITION: + /* Only master mtd device must be used to add partitions */ + if (mtd_is_partition(mtd)) + return -EINVAL; + return mtd_add_partition(mtd, p.devname, p.start, p.length); case BLKPG_DEL_PARTITION: @@ -601,6 +601,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) } case MEMGETINFO: + memset(&info, 0, sizeof(info)); info.type = mtd->type; info.flags = mtd->flags; info.size = mtd->size; @@ -609,7 +610,6 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) info.oobsize = mtd->oobsize; /* The below fields are obsolete */ info.ecctype = -1; - info.eccsize = 0; if (copy_to_user(argp, &info, sizeof(struct mtd_info_user))) return -EFAULT; break; diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 79e3689f1e16..1047ff0a4f55 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -720,19 +720,19 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types, } EXPORT_SYMBOL_GPL(parse_mtd_partitions); -int mtd_is_master(struct mtd_info *mtd) +int mtd_is_partition(struct mtd_info *mtd) { struct mtd_part *part; - int nopart = 0; + int ispart = 0; mutex_lock(&mtd_partitions_mutex); list_for_each_entry(part, &mtd_partitions, list) if (&part->mtd == mtd) { - nopart = 1; + ispart = 1; break; } mutex_unlock(&mtd_partitions_mutex); - return nopart; + return ispart; } -EXPORT_SYMBOL_GPL(mtd_is_master); +EXPORT_SYMBOL_GPL(mtd_is_partition); diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index c141b07b25d1..7a13d42cbabd 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -388,6 +388,8 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, "page_addr: 0x%x, column: 0x%x.\n", page_addr, column); + elbc_fcm_ctrl->column = column; + elbc_fcm_ctrl->oob = 0; elbc_fcm_ctrl->use_mdr = 1; fcr = (NAND_CMD_STATUS << FCR_CMD1_SHIFT) | diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 02edfba25b0c..205b10b9f9b9 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -31,6 +31,7 @@ #include <linux/io.h> #include <linux/slab.h> #include <linux/mtd/fsmc.h> +#include <linux/amba/bus.h> #include <mtd/mtd-abi.h> static struct nand_ecclayout fsmc_ecc1_layout = { @@ -119,21 +120,36 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = { } }; -/* - * Default partition tables to be used if the partition information not - * provided through platform data - */ -#define PARTITION(n, off, sz) {.name = n, .offset = off, .size = sz} +#ifdef CONFIG_MTD_PARTITIONS /* + * Default partition tables to be used if the partition information not + * provided through platform data. + * * Default partition layout for small page(= 512 bytes) devices * Size for "Root file system" is updated in driver based on actual device size */ static struct mtd_partition partition_info_16KB_blk[] = { - PARTITION("X-loader", 0, 4 * 0x4000), - PARTITION("U-Boot", 0x10000, 20 * 0x4000), - PARTITION("Kernel", 0x60000, 256 * 0x4000), - PARTITION("Root File System", 0x460000, 0), + { + .name = "X-loader", + .offset = 0, + .size = 4*0x4000, + }, + { + .name = "U-Boot", + .offset = 0x10000, + .size = 20*0x4000, + }, + { + .name = "Kernel", + .offset = 0x60000, + .size = 256*0x4000, + }, + { + .name = "Root File System", + .offset = 0x460000, + .size = 0, + }, }; /* @@ -141,19 +157,37 @@ static struct mtd_partition partition_info_16KB_blk[] = { * Size for "Root file system" is updated in driver based on actual device size */ static struct mtd_partition partition_info_128KB_blk[] = { - PARTITION("X-loader", 0, 4 * 0x20000), - PARTITION("U-Boot", 0x80000, 12 * 0x20000), - PARTITION("Kernel", 0x200000, 48 * 0x20000), - PARTITION("Root File System", 0x800000, 0), + { + .name = "X-loader", + .offset = 0, + .size = 4*0x20000, + }, + { + .name = "U-Boot", + .offset = 0x80000, + .size = 12*0x20000, + }, + { + .name = "Kernel", + .offset = 0x200000, + .size = 48*0x20000, + }, + { + .name = "Root File System", + .offset = 0x800000, + .size = 0, + }, }; #ifdef CONFIG_MTD_CMDLINE_PARTS const char *part_probes[] = { "cmdlinepart", NULL }; #endif +#endif /** - * struct fsmc_nand_data - atructure for FSMC NAND device state + * struct fsmc_nand_data - structure for FSMC NAND device state * + * @pid: Part ID on the AMBA PrimeCell format * @mtd: MTD info for a NAND flash. * @nand: Chip related info for a NAND flash. * @partitions: Partition info for a NAND Flash. @@ -169,6 +203,7 @@ const char *part_probes[] = { "cmdlinepart", NULL }; * @regs_va: FSMC regs base address. */ struct fsmc_nand_data { + u32 pid; struct mtd_info mtd; struct nand_chip nand; struct mtd_partition *partitions; @@ -508,7 +543,9 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) struct nand_chip *nand; struct fsmc_regs *regs; struct resource *res; - int nr_parts, ret = 0; + int ret = 0; + u32 pid; + int i; if (!pdata) { dev_err(&pdev->dev, "platform data is NULL\n"); @@ -598,6 +635,18 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) if (ret) goto err_probe1; + /* + * This device ID is actually a common AMBA ID as used on the + * AMBA PrimeCell bus. However it is not a PrimeCell. + */ + for (pid = 0, i = 0; i < 4; i++) + pid |= (readl(host->regs_va + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8); + host->pid = pid; + dev_info(&pdev->dev, "FSMC device partno %03x, manufacturer %02x, " + "revision %02x, config %02x\n", + AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid), + AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid)); + host->bank = pdata->bank; host->select_chip = pdata->select_bank; regs = host->regs_va; @@ -625,7 +674,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16); - if (get_fsmc_version(host->regs_va) == FSMC_VER8) { + if (AMBA_REV_BITS(host->pid) >= 8) { nand->ecc.read_page = fsmc_read_page_hwecc; nand->ecc.calculate = fsmc_read_hwecc_ecc4; nand->ecc.correct = fsmc_correct_data; @@ -645,7 +694,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) goto err_probe; } - if (get_fsmc_version(host->regs_va) == FSMC_VER8) { + if (AMBA_REV_BITS(host->pid) >= 8) { if (host->mtd.writesize == 512) { nand->ecc.layout = &fsmc_ecc4_sp_layout; host->ecc_place = &fsmc_ecc4_sp_place; @@ -676,11 +725,9 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) * Check if partition info passed via command line */ host->mtd.name = "nand"; - nr_parts = parse_mtd_partitions(&host->mtd, part_probes, + host->nr_partitions = parse_mtd_partitions(&host->mtd, part_probes, &host->partitions, 0); - if (nr_parts > 0) { - host->nr_partitions = nr_parts; - } else { + if (host->nr_partitions <= 0) { #endif /* * Check if partition info passed via command line diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index 67343fc31bd5..cea38a5d4ac5 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -251,58 +251,6 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat, return 0; } - -/* Copy paste of nand_read_page_hwecc_oob_first except for different eccpos - * handling. The ecc area is for 4k chips 72 bytes long and thus does not fit - * into the eccpos array. */ -static int jz_nand_read_page_hwecc_oob_first(struct mtd_info *mtd, - struct nand_chip *chip, uint8_t *buf, int page) -{ - int i, eccsize = chip->ecc.size; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - uint8_t *p = buf; - unsigned int ecc_offset = chip->page_shift; - - /* Read the OOB area first */ - chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); - chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); - - for (i = ecc_offset; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { - int stat; - - chip->ecc.hwctl(mtd, NAND_ECC_READ); - chip->read_buf(mtd, p, eccsize); - - stat = chip->ecc.correct(mtd, p, &chip->oob_poi[i], NULL); - if (stat < 0) - mtd->ecc_stats.failed++; - else - mtd->ecc_stats.corrected += stat; - } - return 0; -} - -/* Copy-and-paste of nand_write_page_hwecc with different eccpos handling. */ -static void jz_nand_write_page_hwecc(struct mtd_info *mtd, - struct nand_chip *chip, const uint8_t *buf) -{ - int i, eccsize = chip->ecc.size; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - const uint8_t *p = buf; - unsigned int ecc_offset = chip->page_shift; - - for (i = ecc_offset; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { - chip->ecc.hwctl(mtd, NAND_ECC_WRITE); - chip->write_buf(mtd, p, eccsize); - chip->ecc.calculate(mtd, p, &chip->oob_poi[i]); - } - - chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); -} - #ifdef CONFIG_MTD_CMDLINE_PARTS static const char *part_probes[] = {"cmdline", NULL}; #endif @@ -393,9 +341,6 @@ static int __devinit jz_nand_probe(struct platform_device *pdev) chip->ecc.size = 512; chip->ecc.bytes = 9; - chip->ecc.read_page = jz_nand_read_page_hwecc_oob_first; - chip->ecc.write_page = jz_nand_write_page_hwecc; - if (pdata) chip->ecc.layout = pdata->ecc_layout; @@ -489,7 +434,7 @@ static int __devexit jz_nand_remove(struct platform_device *pdev) return 0; } -struct platform_driver jz_nand_driver = { +static struct platform_driver jz_nand_driver = { .probe = jz_nand_probe, .remove = __devexit_p(jz_nand_remove), .driver = { diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 214b03afdd48..ef932ba55a0b 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1009,7 +1009,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) struct mxc_nand_platform_data *pdata = pdev->dev.platform_data; struct mxc_nand_host *host; struct resource *res; - int err = 0, nr_parts = 0; + int err = 0, __maybe_unused nr_parts = 0; struct nand_ecclayout *oob_smallpage, *oob_largepage; /* Allocate memory for MTD device structure and private data */ diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1f75a1b1f7c3..33550c43acc2 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1782,6 +1782,13 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, else len = mtd->oobsize; + /* Do not allow read past end of page */ + if ((ops->ooboffs + readlen) > len) { + DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to read " + "past end of page\n", __func__); + return -EINVAL; + } + if (unlikely(ops->ooboffs >= len)) { DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to start read " "outside oob\n", __func__); @@ -2377,7 +2384,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, return -EINVAL; } - /* Do not allow reads past end of device */ + /* Do not allow write past end of device */ if (unlikely(to >= mtd->size || ops->ooboffs + ops->ooblen > ((mtd->size >> chip->page_shift) - @@ -2887,7 +2894,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, mtd->writesize = le32_to_cpu(p->byte_per_page); mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize; mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); - chip->chipsize = le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; + chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; busw = 0; if (le16_to_cpu(p->features) & 1) busw = NAND_BUSWIDTH_16; diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 586b981f0e61..6ebd869993aa 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -1092,7 +1092,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) /** * verify_bbt_descr - verify the bad block description - * @bd: the table to verify + * @mtd: MTD device structure + * @bd: the table to verify * * This functions performs a few sanity checks on the bad block description * table. diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index a6a73aab1253..a5aa99f014ba 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -210,12 +210,12 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d #define STATE_CMD_READ0 0x00000001 /* read data from the beginning of page */ #define STATE_CMD_READ1 0x00000002 /* read data from the second half of page */ #define STATE_CMD_READSTART 0x00000003 /* read data second command (large page devices) */ -#define STATE_CMD_PAGEPROG 0x00000004 /* start page programm */ +#define STATE_CMD_PAGEPROG 0x00000004 /* start page program */ #define STATE_CMD_READOOB 0x00000005 /* read OOB area */ #define STATE_CMD_ERASE1 0x00000006 /* sector erase first command */ #define STATE_CMD_STATUS 0x00000007 /* read status */ #define STATE_CMD_STATUS_M 0x00000008 /* read multi-plane status (isn't implemented) */ -#define STATE_CMD_SEQIN 0x00000009 /* sequential data imput */ +#define STATE_CMD_SEQIN 0x00000009 /* sequential data input */ #define STATE_CMD_READID 0x0000000A /* read ID */ #define STATE_CMD_ERASE2 0x0000000B /* sector erase second command */ #define STATE_CMD_RESET 0x0000000C /* reset */ @@ -230,7 +230,7 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d #define STATE_ADDR_ZERO 0x00000040 /* one byte zero address was accepted */ #define STATE_ADDR_MASK 0x00000070 /* address states mask */ -/* Durind data input/output the simulator is in these states */ +/* During data input/output the simulator is in these states */ #define STATE_DATAIN 0x00000100 /* waiting for data input */ #define STATE_DATAIN_MASK 0x00000100 /* data input states mask */ @@ -248,7 +248,7 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d /* Simulator's actions bit masks */ #define ACTION_CPY 0x00100000 /* copy page/OOB to the internal buffer */ -#define ACTION_PRGPAGE 0x00200000 /* programm the internal buffer to flash */ +#define ACTION_PRGPAGE 0x00200000 /* program the internal buffer to flash */ #define ACTION_SECERASE 0x00300000 /* erase sector */ #define ACTION_ZEROOFF 0x00400000 /* don't add any offset to address */ #define ACTION_HALFOFF 0x00500000 /* add to address half of page */ @@ -263,18 +263,18 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d #define OPT_PAGE512 0x00000002 /* 512-byte page chips */ #define OPT_PAGE2048 0x00000008 /* 2048-byte page chips */ #define OPT_SMARTMEDIA 0x00000010 /* SmartMedia technology chips */ -#define OPT_AUTOINCR 0x00000020 /* page number auto inctimentation is possible */ +#define OPT_AUTOINCR 0x00000020 /* page number auto incrementation is possible */ #define OPT_PAGE512_8BIT 0x00000040 /* 512-byte page chips with 8-bit bus width */ #define OPT_PAGE4096 0x00000080 /* 4096-byte page chips */ #define OPT_LARGEPAGE (OPT_PAGE2048 | OPT_PAGE4096) /* 2048 & 4096-byte page chips */ #define OPT_SMALLPAGE (OPT_PAGE256 | OPT_PAGE512) /* 256 and 512-byte page chips */ -/* Remove action bits ftom state */ +/* Remove action bits from state */ #define NS_STATE(x) ((x) & ~ACTION_MASK) /* * Maximum previous states which need to be saved. Currently saving is - * only needed for page programm operation with preceeded read command + * only needed for page program operation with preceded read command * (which is only valid for 512-byte pages). */ #define NS_MAX_PREVSTATES 1 @@ -380,16 +380,16 @@ static struct nandsim_operations { /* Read OOB */ {OPT_SMALLPAGE, {STATE_CMD_READOOB | ACTION_OOBOFF, STATE_ADDR_PAGE | ACTION_CPY, STATE_DATAOUT, STATE_READY}}, - /* Programm page starting from the beginning */ + /* Program page starting from the beginning */ {OPT_ANY, {STATE_CMD_SEQIN, STATE_ADDR_PAGE, STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}}, - /* Programm page starting from the beginning */ + /* Program page starting from the beginning */ {OPT_SMALLPAGE, {STATE_CMD_READ0, STATE_CMD_SEQIN | ACTION_ZEROOFF, STATE_ADDR_PAGE, STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}}, - /* Programm page starting from the second half */ + /* Program page starting from the second half */ {OPT_PAGE512, {STATE_CMD_READ1, STATE_CMD_SEQIN | ACTION_HALFOFF, STATE_ADDR_PAGE, STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}}, - /* Programm OOB */ + /* Program OOB */ {OPT_SMALLPAGE, {STATE_CMD_READOOB, STATE_CMD_SEQIN | ACTION_OOBOFF, STATE_ADDR_PAGE, STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}}, /* Erase sector */ @@ -470,7 +470,7 @@ static int alloc_device(struct nandsim *ns) err = -EINVAL; goto err_close; } - ns->pages_written = vmalloc(ns->geom.pgnum); + ns->pages_written = vzalloc(ns->geom.pgnum); if (!ns->pages_written) { NS_ERR("alloc_device: unable to allocate pages written array\n"); err = -ENOMEM; @@ -483,7 +483,6 @@ static int alloc_device(struct nandsim *ns) goto err_free; } ns->cfile = cfile; - memset(ns->pages_written, 0, ns->geom.pgnum); return 0; } @@ -1171,9 +1170,9 @@ static inline void switch_to_ready_state(struct nandsim *ns, u_char status) * of supported operations. * * Operation can be unknown because of the following. - * 1. New command was accepted and this is the firs call to find the + * 1. New command was accepted and this is the first call to find the * correspondent states chain. In this case ns->npstates = 0; - * 2. There is several operations which begin with the same command(s) + * 2. There are several operations which begin with the same command(s) * (for example program from the second half and read from the * second half operations both begin with the READ1 command). In this * case the ns->pstates[] array contains previous states. @@ -1186,7 +1185,7 @@ static inline void switch_to_ready_state(struct nandsim *ns, u_char status) * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is * zeroed). * - * If there are several maches, the current state is pushed to the + * If there are several matches, the current state is pushed to the * ns->pstates. * * The operation can be unknown only while commands are input to the chip. @@ -1195,10 +1194,10 @@ static inline void switch_to_ready_state(struct nandsim *ns, u_char status) * operation is searched using the following pattern: * ns->pstates[0], ... ns->pstates[ns->npstates], <address input> * - * It is supposed that this pattern must either match one operation on + * It is supposed that this pattern must either match one operation or * none. There can't be ambiguity in that case. * - * If no matches found, the functions does the following: + * If no matches found, the function does the following: * 1. if there are saved states present, try to ignore them and search * again only using the last command. If nothing was found, switch * to the STATE_READY state. @@ -1668,7 +1667,7 @@ static int do_state_action(struct nandsim *ns, uint32_t action) case ACTION_PRGPAGE: /* - * Programm page - move internal buffer data to the page. + * Program page - move internal buffer data to the page. */ if (ns->lines.wp) { @@ -1933,7 +1932,7 @@ static u_char ns_nand_read_byte(struct mtd_info *mtd) NS_DBG("read_byte: all bytes were read\n"); /* - * The OPT_AUTOINCR allows to read next conseqitive pages without + * The OPT_AUTOINCR allows to read next consecutive pages without * new read operation cycle. */ if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) { diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 6ddb2461d740..bb277a54986f 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -107,7 +107,7 @@ static int __devinit pasemi_nand_probe(struct platform_device *ofdev, if (pasemi_nand_mtd) return -ENODEV; - pr_debug("pasemi_nand at %llx-%llx\n", res.start, res.end); + pr_debug("pasemi_nand at %pR\n", &res); /* Allocate memory for MTD device structure and private data */ pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) + diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 9f322f1a7f22..da25a90af4a4 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -108,8 +108,9 @@ static void wait_warn(char *msg, int state, unsigned int ctrl, static int omap2_onenand_wait(struct mtd_info *mtd, int state) { struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); + struct onenand_chip *this = mtd->priv; unsigned int intr = 0; - unsigned int ctrl; + unsigned int ctrl, ctrl_mask; unsigned long timeout; u32 syscfg; @@ -180,7 +181,8 @@ retry: if (result == 0) { /* Timeout after 20ms */ ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS); - if (ctrl & ONENAND_CTRL_ONGO) { + if (ctrl & ONENAND_CTRL_ONGO && + !this->ongoing) { /* * The operation seems to be still going * so give it some more time. @@ -269,7 +271,11 @@ retry: return -EIO; } - if (ctrl & 0xFE9F) + ctrl_mask = 0xFE9F; + if (this->ongoing) + ctrl_mask &= ~0x8000; + + if (ctrl & ctrl_mask) wait_warn("unexpected controller status", state, ctrl, intr); return 0; diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 6b3a875647c9..c38bf9c54a11 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -400,8 +400,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le value = onenand_bufferram_address(this, block); this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); - if (ONENAND_IS_MLC(this) || ONENAND_IS_2PLANE(this) || - ONENAND_IS_4KB_PAGE(this)) + if (ONENAND_IS_2PLANE(this) || ONENAND_IS_4KB_PAGE(this)) /* It is always BufferRAM0 */ ONENAND_SET_BUFFERRAM0(this); else @@ -430,7 +429,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le case FLEXONENAND_CMD_RECOVER_LSB: case ONENAND_CMD_READ: case ONENAND_CMD_READOOB: - if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this)) + if (ONENAND_IS_4KB_PAGE(this)) /* It is always BufferRAM0 */ dataram = ONENAND_SET_BUFFERRAM0(this); else @@ -1353,7 +1352,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from, stats = mtd->ecc_stats; - readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; + readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; while (read < len) { cond_resched(); @@ -1429,7 +1428,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, int ret; onenand_get_device(mtd, FL_READING); - ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ? + ret = ONENAND_IS_4KB_PAGE(this) ? onenand_mlc_read_ops_nolock(mtd, from, &ops) : onenand_read_ops_nolock(mtd, from, &ops); onenand_release_device(mtd); @@ -1464,7 +1463,7 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from, onenand_get_device(mtd, FL_READING); if (ops->datbuf) - ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ? + ret = ONENAND_IS_4KB_PAGE(this) ? onenand_mlc_read_ops_nolock(mtd, from, ops) : onenand_read_ops_nolock(mtd, from, ops); else @@ -1558,7 +1557,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, column = from & (mtd->oobsize - 1); - readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; + readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; while (read < len) { cond_resched(); @@ -1612,7 +1611,7 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to u_char *oob_buf = this->oob_buf; int status, i, readcmd; - readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; + readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; this->command(mtd, readcmd, to, mtd->oobsize); onenand_update_bufferram(mtd, to, 0); @@ -1845,7 +1844,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, const u_char *buf = ops->datbuf; const u_char *oob = ops->oobbuf; u_char *oobbuf; - int ret = 0; + int ret = 0, cmd; DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n", __func__, (unsigned int) to, (int) len); @@ -1954,7 +1953,19 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, ONENAND_SET_NEXT_BUFFERRAM(this); } - this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); + this->ongoing = 0; + cmd = ONENAND_CMD_PROG; + + /* Exclude 1st OTP and OTP blocks for cache program feature */ + if (ONENAND_IS_CACHE_PROGRAM(this) && + likely(onenand_block(this, to) != 0) && + ONENAND_IS_4KB_PAGE(this) && + ((written + thislen) < len)) { + cmd = ONENAND_CMD_2X_CACHE_PROG; + this->ongoing = 1; + } + + this->command(mtd, cmd, to, mtd->writesize); /* * 2 PLANE, MLC, and Flex-OneNAND wait here @@ -2067,7 +2078,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, oobbuf = this->oob_buf; - oobcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB; + oobcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB; /* Loop until all data write */ while (written < len) { @@ -2086,7 +2097,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, memcpy(oobbuf + column, buf, thislen); this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); - if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this)) { + if (ONENAND_IS_4KB_PAGE(this)) { /* Set main area of DataRAM to 0xff*/ memset(this->page_buf, 0xff, mtd->writesize); this->write_bufferram(mtd, ONENAND_DATARAM, @@ -3029,7 +3040,7 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len, this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); this->wait(mtd, FL_OTPING); - ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ? + ret = ONENAND_IS_4KB_PAGE(this) ? onenand_mlc_read_ops_nolock(mtd, from, &ops) : onenand_read_ops_nolock(mtd, from, &ops); @@ -3377,8 +3388,10 @@ static void onenand_check_features(struct mtd_info *mtd) case ONENAND_DEVICE_DENSITY_4Gb: if (ONENAND_IS_DDP(this)) this->options |= ONENAND_HAS_2PLANE; - else if (numbufs == 1) + else if (numbufs == 1) { this->options |= ONENAND_HAS_4KB_PAGE; + this->options |= ONENAND_HAS_CACHE_PROGRAM; + } case ONENAND_DEVICE_DENSITY_2Gb: /* 2Gb DDP does not have 2 plane */ @@ -3399,7 +3412,11 @@ static void onenand_check_features(struct mtd_info *mtd) break; } - if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this)) + /* The MLC has 4KiB pagesize. */ + if (ONENAND_IS_MLC(this)) + this->options |= ONENAND_HAS_4KB_PAGE; + + if (ONENAND_IS_4KB_PAGE(this)) this->options &= ~ONENAND_HAS_2PLANE; if (FLEXONENAND(this)) { @@ -3415,6 +3432,8 @@ static void onenand_check_features(struct mtd_info *mtd) printk(KERN_DEBUG "Chip has 2 plane\n"); if (this->options & ONENAND_HAS_4KB_PAGE) printk(KERN_DEBUG "Chip has 4KiB pagesize\n"); + if (this->options & ONENAND_HAS_CACHE_PROGRAM) + printk(KERN_DEBUG "Chip has cache program feature\n"); } /** @@ -3831,7 +3850,7 @@ static int onenand_probe(struct mtd_info *mtd) /* The data buffer size is equal to page size */ mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); /* We use the full BufferRAM */ - if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this)) + if (ONENAND_IS_4KB_PAGE(this)) mtd->writesize <<= 1; mtd->oobsize = mtd->writesize >> 5; diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index 01ab5b3c453b..905209bf9465 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c @@ -91,13 +91,15 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr for (j = 0; j < len; j++) { /* No need to read pages fully, * just read required OOB bytes */ - ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops); + ret = onenand_bbt_read_oob(mtd, + from + j * this->writesize + bd->offs, &ops); /* If it is a initial bad block, just ignore it */ if (ret == ONENAND_BBT_READ_FATAL_ERROR) return -EIO; - if (ret || check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { + if (ret || check_short_pattern(&buf[j * scanlen], + scanlen, this->writesize, bd)) { bbm->bbt[i >> 3] |= 0x03 << (i & 0x6); printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", i >> 1, (unsigned int) from); diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c index 0de7a05e6de0..a4c74a9ba430 100644 --- a/drivers/mtd/onenand/samsung.c +++ b/drivers/mtd/onenand/samsung.c @@ -651,7 +651,7 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, void __iomem *p; void *buf = (void *) buffer; dma_addr_t dma_src, dma_dst; - int err, page_dma = 0; + int err, ofs, page_dma = 0; struct device *dev = &onenand->pdev->dev; p = this->base + area; @@ -677,10 +677,13 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, if (!page) goto normal; + /* Page offset */ + ofs = ((size_t) buf & ~PAGE_MASK); page_dma = 1; + /* DMA routine */ dma_src = onenand->phys_base + (p - this->base); - dma_dst = dma_map_page(dev, page, 0, count, DMA_FROM_DEVICE); + dma_dst = dma_map_page(dev, page, ofs, count, DMA_FROM_DEVICE); } else { /* DMA routine */ dma_src = onenand->phys_base + (p - this->base); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index fcdb7f65fe0b..0b8141fc5c26 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -425,12 +425,11 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, /* Read both LEB 0 and LEB 1 into memory */ ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { - leb[seb->lnum] = vmalloc(ubi->vtbl_size); + leb[seb->lnum] = vzalloc(ubi->vtbl_size); if (!leb[seb->lnum]) { err = -ENOMEM; goto out_free; } - memset(leb[seb->lnum], 0, ubi->vtbl_size); err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0, ubi->vtbl_size); @@ -516,10 +515,9 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, int i; struct ubi_vtbl_record *vtbl; - vtbl = vmalloc(ubi->vtbl_size); + vtbl = vzalloc(ubi->vtbl_size); if (!vtbl) return ERR_PTR(-ENOMEM); - memset(vtbl, 0, ubi->vtbl_size); for (i = 0; i < ubi->vtbl_slots; i++) memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE); |