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

* git://git.infradead.org/mtd-2.6: (67 commits)
  [MTD] [MAPS] Fix printk format warning in nettel.c
  [MTD] [NAND] add cmdline parsing (mtdparts=) support to cafe_nand
  [MTD] CFI: remove major/minor version check for command set 0x0002
  [MTD] [NAND] ndfc driver
  [MTD] [TESTS] Fix some size_t printk format warnings
  [MTD] LPDDR Makefile and KConfig
  [MTD] LPDDR extended physmap driver to support LPDDR flash
  [MTD] LPDDR added new pfow_base parameter
  [MTD] LPDDR Command set driver
  [MTD] LPDDR PFOW definition
  [MTD] LPDDR QINFO records definitions
  [MTD] LPDDR qinfo probing.
  [MTD] [NAND] pxa3xx: convert from ns to clock ticks more accurately
  [MTD] [NAND] pxa3xx: fix non-page-aligned reads
  [MTD] [NAND] fix nandsim sched.h references
  [MTD] [NAND] alauda: use USB API functions rather than constants
  [MTD] struct device - replace bus_id with dev_name(), dev_set_name()
  [MTD] fix m25p80 64-bit divisions
  [MTD] fix dataflash 64-bit divisions
  [MTD] [NAND] Set the fsl elbc ECCM according the settings in bootloader.
  ...

Fixed up trivial debug conflicts in drivers/mtd/devices/{m25p80.c,mtd_dataflash.c}
This commit is contained in:
Linus Torvalds
2009-01-09 12:36:45 -08:00
89 changed files with 6159 additions and 696 deletions
@@ -0,0 +1,39 @@
AMCC NDFC (NanD Flash Controller)
Required properties:
- compatible : "ibm,ndfc".
- reg : should specify chip select and size used for the chip (0x2000).
Optional properties:
- ccr : NDFC config and control register value (default 0).
- bank-settings : NDFC bank configuration register value (default 0).
Notes:
- partition(s) - follows the OF MTD standard for partitions
Example:
ndfc@1,0 {
compatible = "ibm,ndfc";
reg = <0x00000001 0x00000000 0x00002000>;
ccr = <0x00001000>;
bank-settings = <0x80002222>;
#address-cells = <1>;
#size-cells = <1>;
nand {
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "kernel";
reg = <0x00000000 0x00200000>;
};
partition@200000 {
label = "root";
reg = <0x00200000 0x03E00000>;
};
};
};
+54
View File
@@ -27,6 +27,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/corgi_lcd.h>
#include <linux/mtd/sharpsl.h>
#include <video/w100fb.h>
#include <asm/setup.h>
@@ -542,6 +543,55 @@ err_free_1:
static inline void corgi_init_spi(void) {}
#endif
static struct mtd_partition sharpsl_nand_partitions[] = {
{
.name = "System Area",
.offset = 0,
.size = 7 * 1024 * 1024,
},
{
.name = "Root Filesystem",
.offset = 7 * 1024 * 1024,
.size = 25 * 1024 * 1024,
},
{
.name = "Home Filesystem",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
static struct nand_bbt_descr sharpsl_bbt = {
.options = 0,
.offs = 4,
.len = 2,
.pattern = scan_ff_pattern
};
static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = {
.badblock_pattern = &sharpsl_bbt,
.partitions = sharpsl_nand_partitions,
.nr_partitions = ARRAY_SIZE(sharpsl_nand_partitions),
};
static struct resource sharpsl_nand_resources[] = {
{
.start = 0x0C000000,
.end = 0x0C000FFF,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device sharpsl_nand_device = {
.name = "sharpsl-nand",
.id = -1,
.resource = sharpsl_nand_resources,
.num_resources = ARRAY_SIZE(sharpsl_nand_resources),
.dev.platform_data = &sharpsl_nand_platform_data,
};
static struct mtd_partition sharpsl_rom_parts[] = {
{
.name ="Boot PROM Filesystem",
@@ -577,6 +627,7 @@ static struct platform_device *devices[] __initdata = {
&corgifb_device,
&corgikbd_device,
&corgiled_device,
&sharpsl_nand_device,
&sharpsl_rom_device,
};
@@ -617,6 +668,9 @@ static void __init corgi_init(void)
platform_scoop_config = &corgi_pcmcia_config;
if (machine_is_husky())
sharpsl_nand_partitions[1].size = 53 * 1024 * 1024;
platform_add_devices(devices, ARRAY_SIZE(devices));
}
+51
View File
@@ -24,6 +24,7 @@
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/mtd/sharpsl.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -414,6 +415,55 @@ static struct pxafb_mach_info poodle_fb_info = {
.lcd_conn = LCD_COLOR_TFT_16BPP,
};
static struct mtd_partition sharpsl_nand_partitions[] = {
{
.name = "System Area",
.offset = 0,
.size = 7 * 1024 * 1024,
},
{
.name = "Root Filesystem",
.offset = 7 * 1024 * 1024,
.size = 22 * 1024 * 1024,
},
{
.name = "Home Filesystem",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
static struct nand_bbt_descr sharpsl_bbt = {
.options = 0,
.offs = 4,
.len = 2,
.pattern = scan_ff_pattern
};
static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = {
.badblock_pattern = &sharpsl_bbt,
.partitions = sharpsl_nand_partitions,
.nr_partitions = ARRAY_SIZE(sharpsl_nand_partitions),
};
static struct resource sharpsl_nand_resources[] = {
{
.start = 0x0C000000,
.end = 0x0C000FFF,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device sharpsl_nand_device = {
.name = "sharpsl-nand",
.id = -1,
.resource = sharpsl_nand_resources,
.num_resources = ARRAY_SIZE(sharpsl_nand_resources),
.dev.platform_data = &sharpsl_nand_platform_data,
};
static struct mtd_partition sharpsl_rom_parts[] = {
{
.name ="Boot PROM Filesystem",
@@ -447,6 +497,7 @@ static struct platform_device sharpsl_rom_device = {
static struct platform_device *devices[] __initdata = {
&poodle_locomo_device,
&poodle_scoop_device,
&sharpsl_nand_device,
&sharpsl_rom_device,
};
+77
View File
@@ -31,6 +31,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/corgi_lcd.h>
#include <linux/mtd/sharpsl.h>
#include <asm/setup.h>
#include <asm/memory.h>
@@ -613,6 +614,54 @@ static struct pxafb_mach_info spitz_pxafb_info = {
.lcd_conn = LCD_COLOR_TFT_16BPP | LCD_ALTERNATE_MAPPING,
};
static struct mtd_partition sharpsl_nand_partitions[] = {
{
.name = "System Area",
.offset = 0,
.size = 7 * 1024 * 1024,
},
{
.name = "Root Filesystem",
.offset = 7 * 1024 * 1024,
},
{
.name = "Home Filesystem",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
static struct nand_bbt_descr sharpsl_bbt = {
.options = 0,
.offs = 4,
.len = 2,
.pattern = scan_ff_pattern
};
static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = {
.badblock_pattern = &sharpsl_bbt,
.partitions = sharpsl_nand_partitions,
.nr_partitions = ARRAY_SIZE(sharpsl_nand_partitions),
};
static struct resource sharpsl_nand_resources[] = {
{
.start = 0x0C000000,
.end = 0x0C000FFF,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device sharpsl_nand_device = {
.name = "sharpsl-nand",
.id = -1,
.resource = sharpsl_nand_resources,
.num_resources = ARRAY_SIZE(sharpsl_nand_resources),
.dev.platform_data = &sharpsl_nand_platform_data,
};
static struct mtd_partition sharpsl_rom_parts[] = {
{
@@ -648,6 +697,7 @@ static struct platform_device *devices[] __initdata = {
&spitzscoop_device,
&spitzkbd_device,
&spitzled_device,
&sharpsl_nand_device,
&sharpsl_rom_device,
};
@@ -671,6 +721,14 @@ static void __init common_init(void)
pm_power_off = spitz_poweroff;
arm_pm_restart = spitz_restart;
if (machine_is_spitz()) {
sharpsl_nand_partitions[1].size = 5 * 1024 * 1024;
} else if (machine_is_akita()) {
sharpsl_nand_partitions[1].size = 58 * 1024 * 1024;
} else if (machine_is_borzoi()) {
sharpsl_nand_partitions[1].size = 32 * 1024 * 1024;
}
PMCR = 0x00;
/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
@@ -715,10 +773,29 @@ static struct i2c_board_info akita_i2c_board_info[] = {
},
};
static struct nand_bbt_descr sharpsl_akita_bbt = {
.options = 0,
.offs = 4,
.len = 1,
.pattern = scan_ff_pattern
};
static struct nand_ecclayout akita_oobinfo = {
.eccbytes = 24,
.eccpos = {
0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
.oobfree = {{0x08, 0x09}}
};
static void __init akita_init(void)
{
spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt;
sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo;
/* We just pretend the second element of the array doesn't exist */
spitz_pcmcia_config.num_devs = 1;
platform_scoop_config = &spitz_pcmcia_config;
+10
View File
@@ -45,6 +45,14 @@ config MTD_PARTITIONS
devices. Partitioning on NFTL 'devices' is a different - that's the
'normal' form of partitioning used on a block device.
config MTD_TESTS
tristate "MTD tests support"
depends on m
help
This option includes various MTD tests into compilation. The tests
should normally be compiled as kernel modules. The modules perform
various checks and verifications when loaded.
config MTD_REDBOOT_PARTS
tristate "RedBoot partition table parsing"
depends on MTD_PARTITIONS
@@ -316,6 +324,8 @@ source "drivers/mtd/nand/Kconfig"
source "drivers/mtd/onenand/Kconfig"
source "drivers/mtd/lpddr/Kconfig"
source "drivers/mtd/ubi/Kconfig"
endif # MTD
+1 -1
View File
@@ -29,6 +29,6 @@ obj-$(CONFIG_MTD_OOPS) += mtdoops.o
nftl-objs := nftlcore.o nftlmount.o
inftl-objs := inftlcore.o inftlmount.o
obj-y += chips/ maps/ devices/ nand/ onenand/
obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/
obj-$(CONFIG_MTD_UBI) += ubi/
+6 -6
View File
@@ -58,8 +58,8 @@ static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t
static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *);
static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_intelext_sync (struct mtd_info *);
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
#ifdef CONFIG_MTD_OTP
static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
@@ -558,8 +558,8 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
}
for (i=0; i<mtd->numeraseregions;i++){
printk(KERN_DEBUG "erase region %d: offset=0x%x,size=0x%x,blocks=%d\n",
i,mtd->eraseregions[i].offset,
printk(KERN_DEBUG "erase region %d: offset=0x%llx,size=0x%x,blocks=%d\n",
i,(unsigned long long)mtd->eraseregions[i].offset,
mtd->eraseregions[i].erasesize,
mtd->eraseregions[i].numblocks);
}
@@ -2058,7 +2058,7 @@ out: put_chip(map, chip, adr);
return ret;
}
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
int ret;
@@ -2082,7 +2082,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
return ret;
}
static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
int ret;
+14 -4
View File
@@ -71,8 +71,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr);
#include "fwh_lock.h"
static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static struct mtd_chip_driver cfi_amdstd_chipdrv = {
.probe = NULL, /* Not usable directly */
@@ -322,6 +322,14 @@ static struct cfi_fixup fixup_table[] = {
};
static void cfi_fixup_major_minor(struct cfi_private *cfi,
struct cfi_pri_amdstd *extp)
{
if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e &&
extp->MajorVersion == '0')
extp->MajorVersion = '1';
}
struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
{
struct cfi_private *cfi = map->fldrv_priv;
@@ -363,6 +371,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
return NULL;
}
cfi_fixup_major_minor(cfi, extp);
if (extp->MajorVersion != '1' ||
(extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
@@ -1774,12 +1784,12 @@ out_unlock:
return ret;
}
static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
return cfi_varsize_frob(mtd, do_atmel_lock, ofs, len, NULL);
}
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
return cfi_varsize_frob(mtd, do_atmel_unlock, ofs, len, NULL);
}
+7 -7
View File
@@ -42,8 +42,8 @@ static int cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen);
static int cfi_staa_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_staa_sync (struct mtd_info *);
static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_staa_suspend (struct mtd_info *);
static void cfi_staa_resume (struct mtd_info *);
@@ -221,8 +221,8 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
}
for (i=0; i<mtd->numeraseregions;i++){
printk(KERN_DEBUG "%d: offset=0x%x,size=0x%x,blocks=%d\n",
i,mtd->eraseregions[i].offset,
printk(KERN_DEBUG "%d: offset=0x%llx,size=0x%x,blocks=%d\n",
i, (unsigned long long)mtd->eraseregions[i].offset,
mtd->eraseregions[i].erasesize,
mtd->eraseregions[i].numblocks);
}
@@ -964,7 +964,7 @@ static int cfi_staa_erase_varsize(struct mtd_info *mtd,
adr += regions[i].erasesize;
len -= regions[i].erasesize;
if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
if (adr % (1<< cfi->chipshift) == (((unsigned long)regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
i++;
if (adr >> cfi->chipshift) {
@@ -1135,7 +1135,7 @@ retry:
spin_unlock_bh(chip->mutex);
return 0;
}
static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -1284,7 +1284,7 @@ retry:
spin_unlock_bh(chip->mutex);
return 0;
}
static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
+2 -2
View File
@@ -77,7 +77,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
}
static int fwh_lock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
static int fwh_lock_varsize(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
int ret;
@@ -88,7 +88,7 @@ static int fwh_lock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
}
static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
int ret;
+2 -4
View File
@@ -619,7 +619,7 @@ static struct mtd_partition lart_partitions[] = {
};
#endif
int __init lart_flash_init (void)
static int __init lart_flash_init (void)
{
int result;
memset (&mtd,0,sizeof (mtd));
@@ -690,7 +690,7 @@ int __init lart_flash_init (void)
return (result);
}
void __exit lart_flash_exit (void)
static void __exit lart_flash_exit (void)
{
#ifndef HAVE_PARTITIONS
del_mtd_device (&mtd);
@@ -705,5 +705,3 @@ module_exit (lart_flash_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Abraham vd Merwe <abraham@2d3d.co.za>");
MODULE_DESCRIPTION("MTD driver for Intel 28F160F3 on LART board");
+21 -20
View File
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/math64.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -169,9 +170,9 @@ static int wait_till_ready(struct m25p *flash)
*/
static int erase_chip(struct m25p *flash)
{
DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB\n",
dev_name(&flash->spi->dev), __func__,
flash->mtd.size / 1024);
DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %lldKiB\n",
dev_name(&flash->spi->dev), __func__,
(long long)(flash->mtd.size >> 10));
/* Wait until finished previous write command. */
if (wait_till_ready(flash))
@@ -232,18 +233,18 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
{
struct m25p *flash = mtd_to_m25p(mtd);
u32 addr,len;
uint32_t rem;
DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
dev_name(&flash->spi->dev), __func__, "at",
(u32)instr->addr, instr->len);
DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%llx, len %lld\n",
dev_name(&flash->spi->dev), __func__, "at",
(long long)instr->addr, (long long)instr->len);
/* sanity checks */
if (instr->addr + instr->len > flash->mtd.size)
return -EINVAL;
if ((instr->addr % mtd->erasesize) != 0
|| (instr->len % mtd->erasesize) != 0) {
div_u64_rem(instr->len, mtd->erasesize, &rem);
if (rem)
return -EINVAL;
}
addr = instr->addr;
len = instr->len;
@@ -677,24 +678,24 @@ static int __devinit m25p_probe(struct spi_device *spi)
flash->mtd.erasesize = info->sector_size;
}
dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name,
flash->mtd.size / 1024);
dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
(long long)flash->mtd.size >> 10);
DEBUG(MTD_DEBUG_LEVEL2,
"mtd .name = %s, .size = 0x%.8x (%uMiB) "
"mtd .name = %s, .size = 0x%llx (%lldMiB) "
".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
flash->mtd.name,
flash->mtd.size, flash->mtd.size / (1024*1024),
(long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
flash->mtd.erasesize, flash->mtd.erasesize / 1024,
flash->mtd.numeraseregions);
if (flash->mtd.numeraseregions)
for (i = 0; i < flash->mtd.numeraseregions; i++)
DEBUG(MTD_DEBUG_LEVEL2,
"mtd.eraseregions[%d] = { .offset = 0x%.8x, "
"mtd.eraseregions[%d] = { .offset = 0x%llx, "
".erasesize = 0x%.8x (%uKiB), "
".numblocks = %d }\n",
i, flash->mtd.eraseregions[i].offset,
i, (long long)flash->mtd.eraseregions[i].offset,
flash->mtd.eraseregions[i].erasesize,
flash->mtd.eraseregions[i].erasesize / 1024,
flash->mtd.eraseregions[i].numblocks);
@@ -722,12 +723,12 @@ static int __devinit m25p_probe(struct spi_device *spi)
if (nr_parts > 0) {
for (i = 0; i < nr_parts; i++) {
DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
"{.name = %s, .offset = 0x%.8x, "
".size = 0x%.8x (%uKiB) }\n",
"{.name = %s, .offset = 0x%llx, "
".size = 0x%llx (%lldKiB) }\n",
i, parts[i].name,
parts[i].offset,
parts[i].size,
parts[i].size / 1024);
(long long)parts[i].offset,
(long long)parts[i].size,
(long long)(parts[i].size >> 10));
}
flash->partitioned = 1;
return add_mtd_partitions(&flash->mtd, parts, nr_parts);
+15 -9
View File
@@ -16,6 +16,7 @@
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/math64.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
@@ -152,15 +153,20 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
struct spi_message msg;
unsigned blocksize = priv->page_size << 3;
uint8_t *command;
uint32_t rem;
DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%x len 0x%x\n",
dev_name(&spi->dev),
instr->addr, instr->len);
DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%llx len 0x%llx\n",
dev_name(&spi->dev), (long long)instr->addr,
(long long)instr->len);
/* Sanity checks */
if ((instr->addr + instr->len) > mtd->size
|| (instr->len % priv->page_size) != 0
|| (instr->addr % priv->page_size) != 0)
if (instr->addr + instr->len > mtd->size)
return -EINVAL;
div_u64_rem(instr->len, priv->page_size, &rem);
if (rem)
return -EINVAL;
div_u64_rem(instr->addr, priv->page_size, &rem);
if (rem)
return -EINVAL;
spi_message_init(&msg);
@@ -178,7 +184,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
/* Calculate flash page address; use block erase (for speed) if
* we're at a block boundary and need to erase the whole block.
*/
pageaddr = instr->addr / priv->page_size;
pageaddr = div_u64(instr->len, priv->page_size);
do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize;
pageaddr = pageaddr << priv->page_offset;
@@ -667,8 +673,8 @@ add_dataflash_otp(struct spi_device *spi, char *name,
if (revision >= 'c')
otp_tag = otp_setup(device, revision);
dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes%s\n",
name, DIV_ROUND_UP(device->size, 1024),
dev_info(&spi->dev, "%s (%lld KBytes) pagesize %d bytes%s\n",
name, (long long)((device->size + 1023) >> 10),
pagesize, otp_tag);
dev_set_drvdata(&spi->dev, priv);
+50 -50
View File
@@ -109,25 +109,25 @@ module_param(shuffle_freq, int, 0);
/* Each memory region corresponds to a minor device */
typedef struct partition_t {
struct mtd_blktrans_dev mbd;
u_int32_t state;
u_int32_t *VirtualBlockMap;
u_int32_t *VirtualPageMap;
u_int32_t FreeTotal;
uint32_t state;
uint32_t *VirtualBlockMap;
uint32_t *VirtualPageMap;
uint32_t FreeTotal;
struct eun_info_t {
u_int32_t Offset;
u_int32_t EraseCount;
u_int32_t Free;
u_int32_t Deleted;
uint32_t Offset;
uint32_t EraseCount;
uint32_t Free;
uint32_t Deleted;
} *EUNInfo;
struct xfer_info_t {
u_int32_t Offset;
u_int32_t EraseCount;
u_int16_t state;
uint32_t Offset;
uint32_t EraseCount;
uint16_t state;
} *XferInfo;
u_int16_t bam_index;
u_int32_t *bam_cache;
u_int16_t DataUnits;
u_int32_t BlocksPerUnit;
uint16_t bam_index;
uint32_t *bam_cache;
uint16_t DataUnits;
uint32_t BlocksPerUnit;
erase_unit_header_t header;
} partition_t;
@@ -199,8 +199,8 @@ static int scan_header(partition_t *part)
static int build_maps(partition_t *part)
{
erase_unit_header_t header;
u_int16_t xvalid, xtrans, i;
u_int blocks, j;
uint16_t xvalid, xtrans, i;
unsigned blocks, j;
int hdr_ok, ret = -1;
ssize_t retval;
loff_t offset;
@@ -269,14 +269,14 @@ static int build_maps(partition_t *part)
/* Set up virtual page map */
blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize;
part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t));
part->VirtualBlockMap = vmalloc(blocks * sizeof(uint32_t));
if (!part->VirtualBlockMap)
goto out_XferInfo;
memset(part->VirtualBlockMap, 0xff, blocks * sizeof(u_int32_t));
memset(part->VirtualBlockMap, 0xff, blocks * sizeof(uint32_t));
part->BlocksPerUnit = (1 << header.EraseUnitSize) >> header.BlockSize;
part->bam_cache = kmalloc(part->BlocksPerUnit * sizeof(u_int32_t),
part->bam_cache = kmalloc(part->BlocksPerUnit * sizeof(uint32_t),
GFP_KERNEL);
if (!part->bam_cache)
goto out_VirtualBlockMap;
@@ -290,7 +290,7 @@ static int build_maps(partition_t *part)
offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
ret = part->mbd.mtd->read(part->mbd.mtd, offset,
part->BlocksPerUnit * sizeof(u_int32_t), &retval,
part->BlocksPerUnit * sizeof(uint32_t), &retval,
(unsigned char *)part->bam_cache);
if (ret)
@@ -332,7 +332,7 @@ out:
======================================================================*/
static int erase_xfer(partition_t *part,
u_int16_t xfernum)
uint16_t xfernum)
{
int ret;
struct xfer_info_t *xfer;
@@ -408,7 +408,7 @@ static int prepare_xfer(partition_t *part, int i)
erase_unit_header_t header;
struct xfer_info_t *xfer;
int nbam, ret;
u_int32_t ctl;
uint32_t ctl;
ssize_t retlen;
loff_t offset;
@@ -430,15 +430,15 @@ static int prepare_xfer(partition_t *part, int i)
}
/* Write the BAM stub */
nbam = (part->BlocksPerUnit * sizeof(u_int32_t) +
nbam = (part->BlocksPerUnit * sizeof(uint32_t) +
le32_to_cpu(part->header.BAMOffset) + SECTOR_SIZE - 1) / SECTOR_SIZE;
offset = xfer->Offset + le32_to_cpu(part->header.BAMOffset);
ctl = cpu_to_le32(BLOCK_CONTROL);
for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) {
for (i = 0; i < nbam; i++, offset += sizeof(uint32_t)) {
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(uint32_t),
&retlen, (u_char *)&ctl);
if (ret)
@@ -461,18 +461,18 @@ static int prepare_xfer(partition_t *part, int i)
======================================================================*/
static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
u_int16_t xferunit)
static int copy_erase_unit(partition_t *part, uint16_t srcunit,
uint16_t xferunit)
{
u_char buf[SECTOR_SIZE];
struct eun_info_t *eun;
struct xfer_info_t *xfer;
u_int32_t src, dest, free, i;
u_int16_t unit;
uint32_t src, dest, free, i;
uint16_t unit;
int ret;
ssize_t retlen;
loff_t offset;
u_int16_t srcunitswap = cpu_to_le16(srcunit);
uint16_t srcunitswap = cpu_to_le16(srcunit);
eun = &part->EUNInfo[srcunit];
xfer = &part->XferInfo[xferunit];
@@ -486,7 +486,7 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
ret = part->mbd.mtd->read(part->mbd.mtd, offset,
part->BlocksPerUnit * sizeof(u_int32_t),
part->BlocksPerUnit * sizeof(uint32_t),
&retlen, (u_char *) (part->bam_cache));
/* mark the cache bad, in case we get an error later */
@@ -503,7 +503,7 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
offset = xfer->Offset + 20; /* Bad! */
unit = cpu_to_le16(0x7fff);
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t),
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(uint16_t),
&retlen, (u_char *) &unit);
if (ret) {
@@ -560,7 +560,7 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
/* All clear? Then update the LogicalEUN again */
ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t),
ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(uint16_t),
&retlen, (u_char *)&srcunitswap);
if (ret) {
@@ -605,8 +605,8 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
static int reclaim_block(partition_t *part)
{
u_int16_t i, eun, xfer;
u_int32_t best;
uint16_t i, eun, xfer;
uint32_t best;
int queued, ret;
DEBUG(0, "ftl_cs: reclaiming space...\n");
@@ -723,10 +723,10 @@ static void dump_lists(partition_t *part)
}
#endif
static u_int32_t find_free(partition_t *part)
static uint32_t find_free(partition_t *part)
{
u_int16_t stop, eun;
u_int32_t blk;
uint16_t stop, eun;
uint32_t blk;
size_t retlen;
int ret;
@@ -749,7 +749,7 @@ static u_int32_t find_free(partition_t *part)
ret = part->mbd.mtd->read(part->mbd.mtd,
part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
part->BlocksPerUnit * sizeof(u_int32_t),
part->BlocksPerUnit * sizeof(uint32_t),
&retlen, (u_char *) (part->bam_cache));
if (ret) {
@@ -786,7 +786,7 @@ static u_int32_t find_free(partition_t *part)
static int ftl_read(partition_t *part, caddr_t buffer,
u_long sector, u_long nblocks)
{
u_int32_t log_addr, bsize;
uint32_t log_addr, bsize;
u_long i;
int ret;
size_t offset, retlen;
@@ -829,14 +829,14 @@ static int ftl_read(partition_t *part, caddr_t buffer,
======================================================================*/
static int set_bam_entry(partition_t *part, u_int32_t log_addr,
u_int32_t virt_addr)
static int set_bam_entry(partition_t *part, uint32_t log_addr,
uint32_t virt_addr)
{
u_int32_t bsize, blk, le_virt_addr;
uint32_t bsize, blk, le_virt_addr;
#ifdef PSYCHO_DEBUG
u_int32_t old_addr;
uint32_t old_addr;
#endif
u_int16_t eun;
uint16_t eun;
int ret;
size_t retlen, offset;
@@ -845,11 +845,11 @@ static int set_bam_entry(partition_t *part, u_int32_t log_addr,
bsize = 1 << part->header.EraseUnitSize;
eun = log_addr / bsize;
blk = (log_addr % bsize) / SECTOR_SIZE;
offset = (part->EUNInfo[eun].Offset + blk * sizeof(u_int32_t) +
offset = (part->EUNInfo[eun].Offset + blk * sizeof(uint32_t) +
le32_to_cpu(part->header.BAMOffset));
#ifdef PSYCHO_DEBUG
ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t),
ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(uint32_t),
&retlen, (u_char *)&old_addr);
if (ret) {
printk(KERN_WARNING"ftl: Error reading old_addr in set_bam_entry: %d\n",ret);
@@ -886,7 +886,7 @@ static int set_bam_entry(partition_t *part, u_int32_t log_addr,
#endif
part->bam_cache[blk] = le_virt_addr;
}
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(uint32_t),
&retlen, (u_char *)&le_virt_addr);
if (ret) {
@@ -900,7 +900,7 @@ static int set_bam_entry(partition_t *part, u_int32_t log_addr,
static int ftl_write(partition_t *part, caddr_t buffer,
u_long sector, u_long nblocks)
{
u_int32_t bsize, log_addr, virt_addr, old_addr, blk;
uint32_t bsize, log_addr, virt_addr, old_addr, blk;
u_long i;
int ret;
size_t retlen, offset;
+1 -1
View File
@@ -50,7 +50,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
struct INFTLrecord *inftl;
unsigned long temp;
if (mtd->type != MTD_NANDFLASH)
if (mtd->type != MTD_NANDFLASH || mtd->size > UINT_MAX)
return;
/* OK, this is moderately ugly. But probably safe. Alternatives? */
if (memcmp(mtd->name, "DiskOnChip", 10))
+2 -2
View File
@@ -63,7 +63,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
* otherwise.
*/
inftl->EraseSize = inftl->mbd.mtd->erasesize;
inftl->nb_blocks = inftl->mbd.mtd->size / inftl->EraseSize;
inftl->nb_blocks = (u32)inftl->mbd.mtd->size / inftl->EraseSize;
inftl->MediaUnit = BLOCK_NIL;
@@ -187,7 +187,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
mh->BlockMultiplierBits);
inftl->EraseSize = inftl->mbd.mtd->erasesize <<
mh->BlockMultiplierBits;
inftl->nb_blocks = inftl->mbd.mtd->size / inftl->EraseSize;
inftl->nb_blocks = (u32)inftl->mbd.mtd->size / inftl->EraseSize;
block >>= mh->BlockMultiplierBits;
}
+22
View File
@@ -0,0 +1,22 @@
# drivers/mtd/chips/Kconfig
menu "LPDDR flash memory drivers"
depends on MTD!=n
config MTD_LPDDR
tristate "Support for LPDDR flash chips"
select MTD_QINFO_PROBE
help
This option enables support of LPDDR (Low power double data rate)
flash chips. Synonymous with Mobile-DDR. It is a new standard for
DDR memories, intended for battery-operated systems.
config MTD_QINFO_PROBE
tristate "Detect flash chips by QINFO probe"
help
Device Information for LPDDR chips is offered through the Overlay
Window QINFO interface, permits software to be used for entire
families of devices. This serves similar purpose of CFI on legacy
Flash products
endmenu
+6
View File
@@ -0,0 +1,6 @@
#
# linux/drivers/mtd/lpddr/Makefile
#
obj-$(CONFIG_MTD_QINFO_PROBE) += qinfo_probe.o
obj-$(CONFIG_MTD_LPDDR) += lpddr_cmds.o
File diff suppressed because it is too large Load Diff
+255
View File
@@ -0,0 +1,255 @@
/*
* Probing flash chips with QINFO records.
* (C) 2008 Korolev Alexey <akorolev@infradead.org>
* (C) 2008 Vasiliy Leonenko <vasiliy.leonenko@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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/mtd/xip.h>
#include <linux/mtd/map.h>
#include <linux/mtd/pfow.h>
#include <linux/mtd/qinfo.h>
static int lpddr_chip_setup(struct map_info *map, struct lpddr_private *lpddr);
struct mtd_info *lpddr_probe(struct map_info *map);
static struct lpddr_private *lpddr_probe_chip(struct map_info *map);
static int lpddr_pfow_present(struct map_info *map,
struct lpddr_private *lpddr);
static struct qinfo_query_info qinfo_array[] = {
/* General device info */
{0, 0, "DevSizeShift", "Device size 2^n bytes"},
{0, 3, "BufSizeShift", "Program buffer size 2^n bytes"},
/* Erase block information */
{1, 1, "TotalBlocksNum", "Total number of blocks"},
{1, 2, "UniformBlockSizeShift", "Uniform block size 2^n bytes"},
/* Partition information */
{2, 1, "HWPartsNum", "Number of hardware partitions"},
/* Optional features */
{5, 1, "SuspEraseSupp", "Suspend erase supported"},
/* Operation typical time */
{10, 0, "SingleWordProgTime", "Single word program 2^n u-sec"},
{10, 1, "ProgBufferTime", "Program buffer write 2^n u-sec"},
{10, 2, "BlockEraseTime", "Block erase 2^n m-sec"},
{10, 3, "FullChipEraseTime", "Full chip erase 2^n m-sec"},
};
static long lpddr_get_qinforec_pos(struct map_info *map, char *id_str)
{
int qinfo_lines = sizeof(qinfo_array)/sizeof(struct qinfo_query_info);
int i;
int bankwidth = map_bankwidth(map) * 8;
int major, minor;
for (i = 0; i < qinfo_lines; i++) {
if (strcmp(id_str, qinfo_array[i].id_str) == 0) {
major = qinfo_array[i].major & ((1 << bankwidth) - 1);
minor = qinfo_array[i].minor & ((1 << bankwidth) - 1);
return minor | (major << bankwidth);
}
}
printk(KERN_ERR"%s qinfo id string is wrong! \n", map->name);
BUG();
return -1;
}
static uint16_t lpddr_info_query(struct map_info *map, char *id_str)
{
unsigned int dsr, val;
int bits_per_chip = map_bankwidth(map) * 8;
unsigned long adr = lpddr_get_qinforec_pos(map, id_str);
int attempts = 20;
/* Write a request for the PFOW record */
map_write(map, CMD(LPDDR_INFO_QUERY),
map->pfow_base + PFOW_COMMAND_CODE);
map_write(map, CMD(adr & ((1 << bits_per_chip) - 1)),
map->pfow_base + PFOW_COMMAND_ADDRESS_L);
map_write(map, CMD(adr >> bits_per_chip),
map->pfow_base + PFOW_COMMAND_ADDRESS_H);
map_write(map, CMD(LPDDR_START_EXECUTION),
map->pfow_base + PFOW_COMMAND_EXECUTE);
while ((attempts--) > 0) {
dsr = CMDVAL(map_read(map, map->pfow_base + PFOW_DSR));
if (dsr & DSR_READY_STATUS)
break;
udelay(10);
}
val = CMDVAL(map_read(map, map->pfow_base + PFOW_COMMAND_DATA));
return val;
}
static int lpddr_pfow_present(struct map_info *map, struct lpddr_private *lpddr)
{
map_word pfow_val[4];
/* Check identification string */
pfow_val[0] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_P);
pfow_val[1] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_F);
pfow_val[2] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_O);
pfow_val[3] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_W);
if (!map_word_equal(map, CMD('P'), pfow_val[0]))
goto out;
if (!map_word_equal(map, CMD('F'), pfow_val[1]))
goto out;
if (!map_word_equal(map, CMD('O'), pfow_val[2]))
goto out;
if (!map_word_equal(map, CMD('W'), pfow_val[3]))
goto out;
return 1; /* "PFOW" is found */
out:
printk(KERN_WARNING"%s: PFOW string at 0x%lx is not found \n",
map->name, map->pfow_base);
return 0;
}
static int lpddr_chip_setup(struct map_info *map, struct lpddr_private *lpddr)
{
lpddr->qinfo = kmalloc(sizeof(struct qinfo_chip), GFP_KERNEL);
if (!lpddr->qinfo) {
printk(KERN_WARNING "%s: no memory for LPDDR qinfo structure\n",
map->name);
return 0;
}
memset(lpddr->qinfo, 0, sizeof(struct qinfo_chip));
/* Get the ManuID */
lpddr->ManufactId = CMDVAL(map_read(map, map->pfow_base + PFOW_MANUFACTURER_ID));
/* Get the DeviceID */
lpddr->DevId = CMDVAL(map_read(map, map->pfow_base + PFOW_DEVICE_ID));
/* read parameters from chip qinfo table */
lpddr->qinfo->DevSizeShift = lpddr_info_query(map, "DevSizeShift");
lpddr->qinfo->TotalBlocksNum = lpddr_info_query(map, "TotalBlocksNum");
lpddr->qinfo->BufSizeShift = lpddr_info_query(map, "BufSizeShift");
lpddr->qinfo->HWPartsNum = lpddr_info_query(map, "HWPartsNum");
lpddr->qinfo->UniformBlockSizeShift =
lpddr_info_query(map, "UniformBlockSizeShift");
lpddr->qinfo->SuspEraseSupp = lpddr_info_query(map, "SuspEraseSupp");
lpddr->qinfo->SingleWordProgTime =
lpddr_info_query(map, "SingleWordProgTime");
lpddr->qinfo->ProgBufferTime = lpddr_info_query(map, "ProgBufferTime");
lpddr->qinfo->BlockEraseTime = lpddr_info_query(map, "BlockEraseTime");
return 1;
}
static struct lpddr_private *lpddr_probe_chip(struct map_info *map)
{
struct lpddr_private lpddr;
struct lpddr_private *retlpddr;
int numvirtchips;
if ((map->pfow_base + 0x1000) >= map->size) {
printk(KERN_NOTICE"%s Probe at base (0x%08lx) past the end of"
"the map(0x%08lx)\n", map->name,
(unsigned long)map->pfow_base, map->size - 1);
return NULL;
}
memset(&lpddr, 0, sizeof(struct lpddr_private));
if (!lpddr_pfow_present(map, &lpddr))
return NULL;
if (!lpddr_chip_setup(map, &lpddr))
return NULL;
/* Ok so we found a chip */
lpddr.chipshift = lpddr.qinfo->DevSizeShift;
lpddr.numchips = 1;
numvirtchips = lpddr.numchips * lpddr.qinfo->HWPartsNum;
retlpddr = kmalloc(sizeof(struct lpddr_private) +
numvirtchips * sizeof(struct flchip), GFP_KERNEL);
if (!retlpddr)
return NULL;
memset(retlpddr, 0, sizeof(struct lpddr_private) +
numvirtchips * sizeof(struct flchip));
memcpy(retlpddr, &lpddr, sizeof(struct lpddr_private));
retlpddr->numchips = numvirtchips;
retlpddr->chipshift = retlpddr->qinfo->DevSizeShift -
__ffs(retlpddr->qinfo->HWPartsNum);
return retlpddr;
}
struct mtd_info *lpddr_probe(struct map_info *map)
{
struct mtd_info *mtd = NULL;
struct lpddr_private *lpddr;
/* First probe the map to see if we havecan open PFOW here */
lpddr = lpddr_probe_chip(map);
if (!lpddr)
return NULL;
map->fldrv_priv = lpddr;
mtd = lpddr_cmdset(map);
if (mtd) {
if (mtd->size > map->size) {
printk(KERN_WARNING "Reducing visibility of %ldKiB chip"
"to %ldKiB\n", (unsigned long)mtd->size >> 10,
(unsigned long)map->size >> 10);
mtd->size = map->size;
}
return mtd;
}
kfree(lpddr->qinfo);
kfree(lpddr);
map->fldrv_priv = NULL;
return NULL;
}
static struct mtd_chip_driver lpddr_chipdrv = {
.probe = lpddr_probe,
.name = "qinfo_probe",
.module = THIS_MODULE
};
static int __init lpddr_probe_init(void)
{
register_mtd_chip_driver(&lpddr_chipdrv);
return 0;
}
static void __exit lpddr_probe_exit(void)
{
unregister_mtd_chip_driver(&lpddr_chipdrv);
}
module_init(lpddr_probe_init);
module_exit(lpddr_probe_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vasiliy Leonenko <vasiliy.leonenko@gmail.com>");
MODULE_DESCRIPTION("Driver to probe qinfo flash chips");

Some files were not shown because too many files have changed in this diff Show More