2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-11-18 15:44:02 +08:00

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

* git://git.infradead.org/mtd-2.6: (226 commits)
  mtd: tests: annotate as DANGEROUS in Kconfig
  mtd: tests: don't use mtd0 as a default
  mtd: clean up usage of MTD_DOCPROBE_ADDRESS
  jffs2: add compr=lzo and compr=zlib options
  jffs2: implement mount option parsing and compression overriding
  mtd: nand: initialize ops.mode
  mtd: provide an alias for the redboot module name
  mtd: m25p80: don't probe device which has status of 'disabled'
  mtd: nand_h1900 never worked
  mtd: Add DiskOnChip G3 support
  mtd: m25p80: add EON flash EN25Q32B into spi flash id table
  mtd: mark block device queue as non-rotational
  mtd: r852: make r852_pm_ops static
  mtd: m25p80: add support for at25df321a spi data flash
  mtd: mxc_nand: preset_v1_v2: unlock all NAND flash blocks
  mtd: nand: switch `check_pattern()' to standard `memcmp()'
  mtd: nand: invalidate cache on unaligned reads
  mtd: nand: do not scan bad blocks with NAND_BBT_NO_OOB set
  mtd: nand: wait to set BBT version
  mtd: nand: scrub BBT on ECC errors
  ...

Fix up trivial conflicts:
 - arch/arm/mach-at91/board-usb-a9260.c
	Merged into board-usb-a926x.c
 - drivers/mtd/maps/lantiq-flash.c
	add_mtd_partitions -> mtd_device_register vs changed to use
	mtd_device_parse_register.
This commit is contained in:
Linus Torvalds 2011-11-07 09:11:16 -08:00
commit e0d65113a7
190 changed files with 7578 additions and 4041 deletions

View File

@ -572,7 +572,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip)
</para>
<para>
The simplest way to activate the FLASH based bad block table support
is to set the option NAND_USE_FLASH_BBT in the option field of
is to set the option NAND_BBT_USE_FLASH in the bbt_option field of
the nand chip structure before calling nand_scan(). For AG-AND
chips is this done by default.
This activates the default FLASH based bad block table functionality
@ -773,20 +773,6 @@ struct nand_oobinfo {
done according to the default builtin scheme.
</para>
</sect2>
<sect2 id="User_space_placement_selection">
<title>User space placement selection</title>
<para>
All non ecc functions like mtd->read and mtd->write use an internal
structure, which can be set by an ioctl. This structure is preset
to the autoplacement default.
<programlisting>
ioctl (fd, MEMSETOOBSEL, oobsel);
</programlisting>
oobsel is a pointer to a user supplied structure of type
nand_oobconfig. The contents of this structure must match the
criteria of the filesystem, which will be used. See an example in utils/nandwrite.c.
</para>
</sect2>
</sect1>
<sect1 id="Spare_area_autoplacement_default">
<title>Spare area autoplacement default schemes</title>
@ -1158,9 +1144,6 @@ in this page</entry>
These constants are defined in nand.h. They are ored together to describe
the functionality.
<programlisting>
/* Use a flash based bad block table. This option is parsed by the
* default bad block table function (nand_default_bbt). */
#define NAND_USE_FLASH_BBT 0x00010000
/* The hw ecc generator provides a syndrome instead a ecc value on read
* This can only work if we have the ecc bytes directly behind the
* data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */

View File

@ -0,0 +1,14 @@
* Atmel Data Flash
Required properties:
- compatible : "atmel,<model>", "atmel,<series>", "atmel,dataflash".
Example:
flash@1 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "atmel,at45db321d", "atmel,at45", "atmel,dataflash";
spi-max-frequency = <25000000>;
reg = <1>;
};

View File

@ -130,19 +130,14 @@ static struct mtd_partition __initdata afeb9260_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(afeb9260_nand_partition);
return afeb9260_nand_partition;
}
static struct atmel_nand_data __initdata afeb9260_nand_data = {
.ale = 21,
.cle = 22,
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
.bus_width_16 = 0,
.parts = afeb9260_nand_partition,
.num_parts = ARRAY_SIZE(afeb9260_nand_partition),
};

View File

@ -132,19 +132,14 @@ static struct mtd_partition __initdata cam60_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(cam60_nand_partition);
return cam60_nand_partition;
}
static struct atmel_nand_data __initdata cam60_nand_data = {
.ale = 21,
.cle = 22,
// .det_pin = ... not there
.rdy_pin = AT91_PIN_PA9,
.enable_pin = AT91_PIN_PA7,
.partition_info = nand_partitions,
.parts = cam60_nand_partition,
.num_parts = ARRAY_SIZE(cam60_nand_partition),
};
static struct sam9_smc_config __initdata cam60_nand_smc_config = {

View File

@ -169,19 +169,14 @@ static struct mtd_partition __initdata cap9adk_nand_partitions[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(cap9adk_nand_partitions);
return cap9adk_nand_partitions;
}
static struct atmel_nand_data __initdata cap9adk_nand_data = {
.ale = 21,
.cle = 22,
// .det_pin = ... not connected
// .rdy_pin = ... not connected
.enable_pin = AT91_PIN_PD15,
.partition_info = nand_partitions,
.parts = cap9adk_nand_partitions,
.num_parts = ARRAY_SIZE(cap9adk_nand_partitions),
};
static struct sam9_smc_config __initdata cap9adk_nand_smc_config = {

View File

@ -97,19 +97,14 @@ static struct mtd_partition __initdata kb9202_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(kb9202_nand_partition);
return kb9202_nand_partition;
}
static struct atmel_nand_data __initdata kb9202_nand_data = {
.ale = 22,
.cle = 21,
// .det_pin = ... not there
.rdy_pin = AT91_PIN_PC29,
.enable_pin = AT91_PIN_PC28,
.partition_info = nand_partitions,
.parts = kb9202_nand_partition,
.num_parts = ARRAY_SIZE(kb9202_nand_partition),
};
static void __init kb9202_board_init(void)

View File

@ -182,19 +182,14 @@ static struct mtd_partition __initdata neocore926_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(neocore926_nand_partition);
return neocore926_nand_partition;
}
static struct atmel_nand_data __initdata neocore926_nand_data = {
.ale = 21,
.cle = 22,
.rdy_pin = AT91_PIN_PB19,
.rdy_pin_active_low = 1,
.enable_pin = AT91_PIN_PD15,
.partition_info = nand_partitions,
.parts = neocore926_nand_partition,
.num_parts = ARRAY_SIZE(neocore926_nand_partition),
};
static struct sam9_smc_config __initdata neocore926_nand_smc_config = {

View File

@ -130,19 +130,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
}
static struct atmel_nand_data __initdata ek_nand_data = {
.ale = 21,
.cle = 22,
// .det_pin = ... not connected
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
.parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition),
};
static struct sam9_smc_config __initdata ek_nand_smc_config = {

View File

@ -138,19 +138,14 @@ static struct mtd_partition __initdata dk_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(dk_nand_partition);
return dk_nand_partition;
}
static struct atmel_nand_data __initdata dk_nand_data = {
.ale = 22,
.cle = 21,
.det_pin = AT91_PIN_PB1,
.rdy_pin = AT91_PIN_PC2,
// .enable_pin = ... not there
.partition_info = nand_partitions,
.parts = dk_nand_partition,
.num_parts = ARRAY_SIZE(dk_nand_partition),
};
#define DK_FLASH_BASE AT91_CHIPSELECT_0

View File

@ -131,19 +131,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
}
static struct atmel_nand_data __initdata ek_nand_data = {
.ale = 21,
.cle = 22,
// .det_pin = ... not connected
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
.parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition),
};
static struct sam9_smc_config __initdata ek_nand_smc_config = {

View File

@ -173,19 +173,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
}
static struct atmel_nand_data __initdata ek_nand_data = {
.ale = 21,
.cle = 22,
// .det_pin = ... not connected
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
.parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition),
};
static struct sam9_smc_config __initdata ek_nand_smc_config = {

View File

@ -179,19 +179,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
}
static struct atmel_nand_data __initdata ek_nand_data = {
.ale = 22,
.cle = 21,
// .det_pin = ... not connected
.rdy_pin = AT91_PIN_PC15,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
.parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition),
};
static struct sam9_smc_config __initdata ek_nand_smc_config = {

View File

@ -180,19 +180,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
}
static struct atmel_nand_data __initdata ek_nand_data = {
.ale = 21,
.cle = 22,
// .det_pin = ... not connected
.rdy_pin = AT91_PIN_PA22,
.enable_pin = AT91_PIN_PD15,
.partition_info = nand_partitions,
.parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition),
};
static struct sam9_smc_config __initdata ek_nand_smc_config = {

View File

@ -157,19 +157,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
}
/* det_pin is not connected */
static struct atmel_nand_data __initdata ek_nand_data = {
.ale = 21,
.cle = 22,
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
.parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition),
};
static struct sam9_smc_config __initdata ek_nand_smc_config = {

View File

@ -137,19 +137,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
}
/* det_pin is not connected */
static struct atmel_nand_data __initdata ek_nand_data = {
.ale = 21,
.cle = 22,
.rdy_pin = AT91_PIN_PC8,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
.parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition),
};
static struct sam9_smc_config __initdata ek_nand_smc_config = {

View File

@ -88,19 +88,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
},
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
}
static struct atmel_nand_data __initdata ek_nand_data = {
.ale = 21,
.cle = 22,
// .det_pin = ... not connected
.rdy_pin = AT91_PIN_PD17,
.enable_pin = AT91_PIN_PB6,
.partition_info = nand_partitions,
.parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition),
};
static struct sam9_smc_config __initdata ek_nand_smc_config = {

View File

@ -97,18 +97,12 @@ static struct mtd_partition __initdata snapper9260_nand_partitions[] = {
},
};
static struct mtd_partition * __init
snapper9260_nand_partition_info(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(snapper9260_nand_partitions);
return snapper9260_nand_partitions;
}
static struct atmel_nand_data __initdata snapper9260_nand_data = {
.ale = 21,
.cle = 22,
.rdy_pin = AT91_PIN_PC13,
.partition_info = snapper9260_nand_partition_info,
.parts = snapper9260_nand_partitions,
.num_parts = ARRAY_SIZE(snapper9260_nand_partitions),
.bus_width_16 = 0,
};

View File

@ -190,19 +190,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
}
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
}
static struct atmel_nand_data __initdata ek_nand_data = {
.ale = 21,
.cle = 22,
// .det_pin = ... not connected
.rdy_pin = AT91_PIN_PA22,
.enable_pin = AT91_PIN_PD15,
.partition_info = nand_partitions,
.parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition),
};
static struct sam9_smc_config __initdata usb_a9260_nand_smc_config = {

View File

@ -172,19 +172,14 @@ static struct mtd_partition __initdata yl9200_nand_partition[] = {
}
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(yl9200_nand_partition);
return yl9200_nand_partition;
}
static struct atmel_nand_data __initdata yl9200_nand_data = {
.ale = 6,
.cle = 7,
// .det_pin = ... not connected
.rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */
.enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */
.partition_info = nand_partitions,
.parts = yl9200_nand_partition,
.num_parts = ARRAY_SIZE(yl9200_nand_partition),
};
/*

View File

@ -117,7 +117,8 @@ struct atmel_nand_data {
u8 ale; /* address line number connected to ALE */
u8 cle; /* address line number connected to CLE */
u8 bus_width_16; /* buswidth is 16 bit */
struct mtd_partition* (*partition_info)(int, int*);
struct mtd_partition *parts;
unsigned int num_parts;
};
extern void __init at91_add_device_nand(struct atmel_nand_data *data);

View File

@ -377,7 +377,7 @@ static struct davinci_nand_pdata da830_evm_nand_pdata = {
.nr_parts = ARRAY_SIZE(da830_evm_nand_partitions),
.ecc_mode = NAND_ECC_HW,
.ecc_bits = 4,
.options = NAND_USE_FLASH_BBT,
.bbt_options = NAND_BBT_USE_FLASH,
.bbt_td = &da830_evm_nand_bbt_main_descr,
.bbt_md = &da830_evm_nand_bbt_mirror_descr,
.timing = &da830_evm_nandflash_timing,

View File

@ -256,7 +256,7 @@ static struct davinci_nand_pdata da850_evm_nandflash_data = {
.nr_parts = ARRAY_SIZE(da850_evm_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
.ecc_bits = 4,
.options = NAND_USE_FLASH_BBT,
.bbt_options = NAND_BBT_USE_FLASH,
.timing = &da850_evm_nandflash_timing,
};

View File

@ -77,7 +77,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
.parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions),
.ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT,
.bbt_options = NAND_BBT_USE_FLASH,
.ecc_bits = 4,
};

View File

@ -74,7 +74,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
.parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions),
.ecc_mode = NAND_ECC_HW_SYNDROME,
.options = NAND_USE_FLASH_BBT,
.bbt_options = NAND_BBT_USE_FLASH,
};
static struct resource davinci_nand_resources[] = {

View File

@ -139,7 +139,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
.parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions),
.ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT,
.bbt_options = NAND_BBT_USE_FLASH,
.ecc_bits = 4,
};

View File

@ -151,7 +151,7 @@ static struct davinci_nand_pdata davinci_evm_nandflash_data = {
.parts = davinci_evm_nandflash_partition,
.nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT,
.bbt_options = NAND_BBT_USE_FLASH,
.timing = &davinci_evm_nandflash_timing,
};

View File

@ -396,7 +396,8 @@ static struct davinci_nand_pdata mityomapl138_nandflash_data = {
.parts = mityomapl138_nandflash_partition,
.nr_parts = ARRAY_SIZE(mityomapl138_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT | NAND_BUSWIDTH_16,
.bbt_options = NAND_BBT_USE_FLASH,
.options = NAND_BUSWIDTH_16,
.ecc_bits = 1, /* 4 bit mode is not supported with 16 bit NAND */
};

View File

@ -87,7 +87,7 @@ static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
.parts = davinci_ntosd2_nandflash_partition,
.nr_parts = ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT,
.bbt_options = NAND_BBT_USE_FLASH,
};
static struct resource davinci_ntosd2_nandflash_resource[] = {

View File

@ -144,7 +144,7 @@ static struct davinci_nand_pdata nand_config = {
.parts = nand_partitions,
.nr_parts = ARRAY_SIZE(nand_partitions),
.ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT,
.bbt_options = NAND_BBT_USE_FLASH,
.ecc_bits = 1,
};

View File

@ -74,8 +74,10 @@ struct davinci_nand_pdata { /* platform_data */
nand_ecc_modes_t ecc_mode;
u8 ecc_bits;
/* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
/* e.g. NAND_BUSWIDTH_16 */
unsigned options;
/* e.g. NAND_BBT_USE_FLASH */
unsigned bbt_options;
/* Main and mirror bbt descriptor overrides */
struct nand_bbt_descr *bbt_td;

View File

@ -116,8 +116,9 @@ static struct mtd_partition ts72xx_nand_parts[] = {
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
.name = "Linux",
.offset = MTDPART_OFS_APPEND,
.size = 0, /* filled in later */
.offset = MTDPART_OFS_RETAIN,
.size = TS72XX_REDBOOT_PART_SIZE,
/* leave so much for last partition */
}, {
.name = "RedBoot",
.offset = MTDPART_OFS_APPEND,
@ -126,28 +127,14 @@ static struct mtd_partition ts72xx_nand_parts[] = {
},
};
static void ts72xx_nand_set_parts(uint64_t size,
struct platform_nand_chip *chip)
{
/* Factory TS-72xx boards only come with 32MiB or 128MiB NAND options */
if (size == SZ_32M || size == SZ_128M) {
/* Set the "Linux" partition size */
ts72xx_nand_parts[1].size = size - TS72XX_REDBOOT_PART_SIZE;
chip->partitions = ts72xx_nand_parts;
chip->nr_partitions = ARRAY_SIZE(ts72xx_nand_parts);
} else {
pr_warning("Unknown nand disk size:%lluMiB\n", size >> 20);
}
}
static struct platform_nand_data ts72xx_nand_data = {
.chip = {
.nr_chips = 1,
.chip_offset = 0,
.chip_delay = 15,
.part_probe_types = ts72xx_nand_part_probes,
.set_parts = ts72xx_nand_set_parts,
.partitions = ts72xx_nand_parts,
.nr_partitions = ARRAY_SIZE(ts72xx_nand_parts),
},
.ctrl = {
.cmd_ctrl = ts72xx_nand_hwcontrol,

View File

@ -167,8 +167,9 @@ static struct mtd_partition aspenite_nand_partitions[] = {
static struct pxa3xx_nand_platform_data aspenite_nand_info = {
.enable_arbiter = 1,
.parts = aspenite_nand_partitions,
.nr_parts = ARRAY_SIZE(aspenite_nand_partitions),
.num_cs = 1,
.parts[0] = aspenite_nand_partitions,
.nr_parts[0] = ARRAY_SIZE(aspenite_nand_partitions),
};
static struct i2c_board_info aspenite_i2c_info[] __initdata = {

View File

@ -275,7 +275,7 @@ static struct platform_nand_data ts78xx_ts_nand_data = {
.partitions = ts78xx_ts_nand_parts,
.nr_partitions = ARRAY_SIZE(ts78xx_ts_nand_parts),
.chip_delay = 15,
.options = NAND_USE_FLASH_BBT,
.bbt_options = NAND_BBT_USE_FLASH,
},
.ctrl = {
/*

View File

@ -424,8 +424,9 @@ static struct mtd_partition cm_x300_nand_partitions[] = {
static struct pxa3xx_nand_platform_data cm_x300_nand_info = {
.enable_arbiter = 1,
.keep_config = 1,
.parts = cm_x300_nand_partitions,
.nr_parts = ARRAY_SIZE(cm_x300_nand_partitions),
.num_cs = 1,
.parts[0] = cm_x300_nand_partitions,
.nr_parts[0] = ARRAY_SIZE(cm_x300_nand_partitions),
};
static void __init cm_x300_init_nand(void)

View File

@ -139,8 +139,9 @@ static struct mtd_partition colibri_nand_partitions[] = {
static struct pxa3xx_nand_platform_data colibri_nand_info = {
.enable_arbiter = 1,
.keep_config = 1,
.parts = colibri_nand_partitions,
.nr_parts = ARRAY_SIZE(colibri_nand_partitions),
.num_cs = 1,
.parts[0] = colibri_nand_partitions,
.nr_parts[0] = ARRAY_SIZE(colibri_nand_partitions),
};
void __init colibri_pxa3xx_init_nand(void)

View File

@ -325,8 +325,9 @@ static struct mtd_partition littleton_nand_partitions[] = {
static struct pxa3xx_nand_platform_data littleton_nand_info = {
.enable_arbiter = 1,
.parts = littleton_nand_partitions,
.nr_parts = ARRAY_SIZE(littleton_nand_partitions),
.num_cs = 1,
.parts[0] = littleton_nand_partitions,
.nr_parts[0] = ARRAY_SIZE(littleton_nand_partitions),
};
static void __init littleton_init_nand(void)

View File

@ -389,10 +389,11 @@ static struct mtd_partition mxm_8x10_nand_partitions[] = {
};
static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = {
.enable_arbiter = 1,
.keep_config = 1,
.parts = mxm_8x10_nand_partitions,
.nr_parts = ARRAY_SIZE(mxm_8x10_nand_partitions)
.enable_arbiter = 1,
.keep_config = 1,
.num_cs = 1,
.parts[0] = mxm_8x10_nand_partitions,
.nr_parts[0] = ARRAY_SIZE(mxm_8x10_nand_partitions)
};
static void __init mxm_8x10_nand_init(void)

View File

@ -346,8 +346,9 @@ static struct mtd_partition raumfeld_nand_partitions[] = {
static struct pxa3xx_nand_platform_data raumfeld_nand_info = {
.enable_arbiter = 1,
.keep_config = 1,
.parts = raumfeld_nand_partitions,
.nr_parts = ARRAY_SIZE(raumfeld_nand_partitions),
.num_cs = 1,
.parts[0] = raumfeld_nand_partitions,
.nr_parts[0] = ARRAY_SIZE(raumfeld_nand_partitions),
};
/**

View File

@ -366,8 +366,9 @@ static struct mtd_partition zylonite_nand_partitions[] = {
static struct pxa3xx_nand_platform_data zylonite_nand_info = {
.enable_arbiter = 1,
.parts = zylonite_nand_partitions,
.nr_parts = ARRAY_SIZE(zylonite_nand_partitions),
.num_cs = 1,
.parts[0] = zylonite_nand_partitions,
.nr_parts[0] = ARRAY_SIZE(zylonite_nand_partitions),
};
static void __init zylonite_init_nand(void)

View File

@ -41,6 +41,19 @@ struct pxa3xx_nand_flash {
struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
};
/*
* Current pxa3xx_nand controller has two chip select which
* both be workable.
*
* Notice should be taken that:
* When you want to use this feature, you should not enable the
* keep configuration feature, for two chip select could be
* attached with different nand chip. The different page size
* and timing requirement make the keep configuration impossible.
*/
/* The max num of chip select current support */
#define NUM_CHIP_SELECT (2)
struct pxa3xx_nand_platform_data {
/* the data flash bus is shared between the Static Memory
@ -52,8 +65,11 @@ struct pxa3xx_nand_platform_data {
/* allow platform code to keep OBM/bootloader defined NFC config */
int keep_config;
const struct mtd_partition *parts;
unsigned int nr_parts;
/* indicate how many chip selects will be used */
int num_cs;
const struct mtd_partition *parts[NUM_CHIP_SELECT];
unsigned int nr_parts[NUM_CHIP_SELECT];
const struct pxa3xx_nand_flash * flash;
size_t num_flash;

View File

@ -90,11 +90,6 @@ static struct mtd_partition nand_partitions[] = {
},
};
static struct mtd_partition *nand_part_info(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(nand_partitions);
return nand_partitions;
}
static struct atmel_nand_data atngw100mkii_nand_data __initdata = {
.cle = 21,
@ -102,7 +97,8 @@ static struct atmel_nand_data atngw100mkii_nand_data __initdata = {
.rdy_pin = GPIO_PIN_PB(28),
.enable_pin = GPIO_PIN_PE(23),
.bus_width_16 = true,
.partition_info = nand_part_info,
.parts = nand_partitions,
.num_parts = ARRAY_SIZE(nand_partitions),
};
#endif

View File

@ -90,18 +90,13 @@ static struct mtd_partition nand_partitions[] = {
},
};
static struct mtd_partition *nand_part_info(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(nand_partitions);
return nand_partitions;
}
static struct atmel_nand_data atstk1006_nand_data __initdata = {
.cle = 21,
.ale = 22,
.rdy_pin = GPIO_PIN_PB(30),
.enable_pin = GPIO_PIN_PB(29),
.partition_info = nand_part_info,
.parts = nand_partitions,
.num_parts = ARRAY_SIZE(num_partitions),
};
#endif

View File

@ -128,7 +128,8 @@ struct atmel_nand_data {
u8 ale; /* address line number connected to ALE */
u8 cle; /* address line number connected to CLE */
u8 bus_width_16; /* buswidth is 16 bit */
struct mtd_partition *(*partition_info)(int size, int *num_partitions);
struct mtd_partition *parts;
unsigned int num_parts;
};
struct platform_device *
at32_add_device_nand(unsigned int id, struct atmel_nand_data *data);

View File

@ -163,7 +163,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
this->ecc.mode = NAND_ECC_SOFT;
/* Enable the following for a flash based bad block table */
/* this->options = NAND_USE_FLASH_BBT; */
/* this->bbt_options = NAND_BBT_USE_FLASH; */
/* Scan to find existence of the device */
if (nand_scan(crisv32_mtd, 1)) {

View File

@ -154,7 +154,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
this->ecc.mode = NAND_ECC_SOFT;
/* Enable the following for a flash based bad block table */
/* this->options = NAND_USE_FLASH_BBT; */
/* this->bbt_options = NAND_BBT_USE_FLASH; */
/* Scan to find existence of the device */
if (nand_scan(crisv32_mtd, 1)) {

View File

@ -12,27 +12,17 @@ menuconfig MTD
if MTD
config MTD_DEBUG
bool "Debugging"
help
This turns on low-level debugging for the entire MTD sub-system.
Normally, you should say 'N'.
config MTD_DEBUG_VERBOSE
int "Debugging verbosity (0 = quiet, 3 = noisy)"
depends on MTD_DEBUG
default "0"
help
Determines the verbosity level of the MTD debugging messages.
config MTD_TESTS
tristate "MTD tests support"
tristate "MTD tests support (DANGEROUS)"
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.
WARNING: some of the tests will ERASE entire MTD device which they
test. Do not use these tests unless you really know what you do.
config MTD_REDBOOT_PARTS
tristate "RedBoot partition table parsing"
---help---
@ -137,7 +127,8 @@ config MTD_AFS_PARTS
'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example.
config MTD_OF_PARTS
def_bool y
tristate "OpenFirmware partitioning information support"
default Y
depends on OF
help
This provides a partition parsing function which derives

View File

@ -5,8 +5,8 @@
# Core functionality.
obj-$(CONFIG_MTD) += mtd.o
mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o
mtd-$(CONFIG_MTD_OF_PARTS) += ofpart.o
obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o

View File

@ -162,8 +162,8 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
}
static int parse_afs_partitions(struct mtd_info *mtd,
struct mtd_partition **pparts,
unsigned long origin)
struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
struct mtd_partition *parts;
u_int mask, off, idx, sz;

View File

@ -47,7 +47,7 @@ struct ar7_bin_rec {
static int create_mtd_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
unsigned long origin)
struct mtd_part_parser_data *data)
{
struct ar7_bin_rec header;
unsigned int offset;

View File

@ -145,8 +145,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd)
if (((major << 8) | minor) < 0x3131) {
/* CFI version 1.0 => don't trust bootloc */
DEBUG(MTD_DEBUG_LEVEL1,
"%s: JEDEC Vendor ID is 0x%02X Device ID is 0x%02X\n",
pr_debug("%s: JEDEC Vendor ID is 0x%02X Device ID is 0x%02X\n",
map->name, cfi->mfr, cfi->id);
/* AFAICS all 29LV400 with a bottom boot block have a device ID
@ -166,8 +165,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd)
* the 8-bit device ID.
*/
(cfi->mfr == CFI_MFR_MACRONIX)) {
DEBUG(MTD_DEBUG_LEVEL1,
"%s: Macronix MX29LV400C with bottom boot block"
pr_debug("%s: Macronix MX29LV400C with bottom boot block"
" detected\n", map->name);
extp->TopBottom = 2; /* bottom boot */
} else
@ -178,8 +176,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd)
extp->TopBottom = 2; /* bottom boot */
}
DEBUG(MTD_DEBUG_LEVEL1,
"%s: AMD CFI PRI V%c.%c has no boot block field;"
pr_debug("%s: AMD CFI PRI V%c.%c has no boot block field;"
" deduced %s from Device ID\n", map->name, major, minor,
extp->TopBottom == 2 ? "bottom" : "top");
}
@ -191,7 +188,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd)
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
if (cfi->cfiq->BufWriteTimeoutTyp) {
DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" );
pr_debug("Using buffer write method\n" );
mtd->write = cfi_amdstd_write_buffers;
}
}
@ -443,8 +440,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
mtd->writesize = 1;
mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): write buffer size %d\n",
__func__, mtd->writebufsize);
pr_debug("MTD %s(): write buffer size %d\n", __func__,
mtd->writebufsize);
mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
@ -1163,7 +1160,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
return ret;
}
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
pr_debug("MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
__func__, adr, datum.x[0] );
/*
@ -1174,7 +1171,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
*/
oldd = map_read(map, adr);
if (map_word_equal(map, oldd, datum)) {
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): NOP\n",
pr_debug("MTD %s(): NOP\n",
__func__);
goto op_done;
}
@ -1400,7 +1397,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
datum = map_word_load(map, buf);
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
pr_debug("MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
__func__, adr, datum.x[0] );
XIP_INVAL_CACHED_RANGE(map, adr, len);
@ -1587,7 +1584,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
return ret;
}
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
pr_debug("MTD %s(): ERASE 0x%.8lx\n",
__func__, chip->start );
XIP_INVAL_CACHED_RANGE(map, adr, map->size);
@ -1675,7 +1672,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
return ret;
}
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
pr_debug("MTD %s(): ERASE 0x%.8lx\n",
__func__, adr );
XIP_INVAL_CACHED_RANGE(map, adr, len);
@ -1801,8 +1798,7 @@ static int do_atmel_lock(struct map_info *map, struct flchip *chip,
goto out_unlock;
chip->state = FL_LOCKING;
DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n",
__func__, adr, len);
pr_debug("MTD %s(): LOCK 0x%08lx len %d\n", __func__, adr, len);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
cfi->device_type, NULL);
@ -1837,8 +1833,7 @@ static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
goto out_unlock;
chip->state = FL_UNLOCKING;
DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n",
__func__, adr, len);
pr_debug("MTD %s(): LOCK 0x%08lx len %d\n", __func__, adr, len);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
cfi->device_type, NULL);

View File

@ -34,8 +34,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
/* Refuse the operation if the we cannot look behind the chip */
if (chip->start < 0x400000) {
DEBUG( MTD_DEBUG_LEVEL3,
"MTD %s(): chip->start: %lx wanted >= 0x400000\n",
pr_debug( "MTD %s(): chip->start: %lx wanted >= 0x400000\n",
__func__, chip->start );
return -EIO;
}

View File

@ -1914,11 +1914,10 @@ static void jedec_reset(u32 base, struct map_info *map, struct cfi_private *cfi)
* (oh and incidentaly the jedec spec - 3.5.3.3) the reset
* sequence is *supposed* to be 0xaa at 0x5555, 0x55 at
* 0x2aaa, 0xF0 at 0x5555 this will not affect the AMD chips
* as they will ignore the writes and dont care what address
* as they will ignore the writes and don't care what address
* the F0 is written to */
if (cfi->addr_unlock1) {
DEBUG( MTD_DEBUG_LEVEL3,
"reset unlock called %x %x \n",
pr_debug( "reset unlock called %x %x \n",
cfi->addr_unlock1,cfi->addr_unlock2);
cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
@ -1941,7 +1940,7 @@ static int cfi_jedec_setup(struct map_info *map, struct cfi_private *cfi, int in
uint8_t uaddr;
if (!(jedec_table[index].devtypes & cfi->device_type)) {
DEBUG(MTD_DEBUG_LEVEL1, "Rejecting potential %s with incompatible %d-bit device type\n",
pr_debug("Rejecting potential %s with incompatible %d-bit device type\n",
jedec_table[index].name, 4 * (1<<cfi->device_type));
return 0;
}
@ -2021,7 +2020,7 @@ static inline int jedec_match( uint32_t base,
* there aren't.
*/
if (finfo->dev_id > 0xff) {
DEBUG( MTD_DEBUG_LEVEL3, "%s(): ID is not 8bit\n",
pr_debug("%s(): ID is not 8bit\n",
__func__);
goto match_done;
}
@ -2045,12 +2044,10 @@ static inline int jedec_match( uint32_t base,
}
/* the part size must fit in the memory window */
DEBUG( MTD_DEBUG_LEVEL3,
"MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
pr_debug("MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
__func__, base, 1 << finfo->dev_size, base + (1 << finfo->dev_size) );
if ( base + cfi_interleave(cfi) * ( 1 << finfo->dev_size ) > map->size ) {
DEBUG( MTD_DEBUG_LEVEL3,
"MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
pr_debug("MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
__func__, finfo->mfr_id, finfo->dev_id,
1 << finfo->dev_size );
goto match_done;
@ -2061,13 +2058,12 @@ static inline int jedec_match( uint32_t base,
uaddr = finfo->uaddr;
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
pr_debug("MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
__func__, cfi->addr_unlock1, cfi->addr_unlock2 );
if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
&& ( unlock_addrs[uaddr].addr1 / cfi->device_type != cfi->addr_unlock1 ||
unlock_addrs[uaddr].addr2 / cfi->device_type != cfi->addr_unlock2 ) ) {
DEBUG( MTD_DEBUG_LEVEL3,
"MTD %s(): 0x%.4x 0x%.4x did not match\n",
pr_debug("MTD %s(): 0x%.4x 0x%.4x did not match\n",
__func__,
unlock_addrs[uaddr].addr1,
unlock_addrs[uaddr].addr2);
@ -2083,15 +2079,13 @@ static inline int jedec_match( uint32_t base,
* FIXME - write a driver that takes all of the chip info as
* module parameters, doesn't probe but forces a load.
*/
DEBUG( MTD_DEBUG_LEVEL3,
"MTD %s(): check ID's disappear when not in ID mode\n",
pr_debug("MTD %s(): check ID's disappear when not in ID mode\n",
__func__ );
jedec_reset( base, map, cfi );
mfr = jedec_read_mfr( map, base, cfi );
id = jedec_read_id( map, base, cfi );
if ( mfr == cfi->mfr && id == cfi->id ) {
DEBUG( MTD_DEBUG_LEVEL3,
"MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
pr_debug("MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
"You might need to manually specify JEDEC parameters.\n",
__func__, cfi->mfr, cfi->id );
goto match_done;
@ -2104,7 +2098,7 @@ static inline int jedec_match( uint32_t base,
* Put the device back in ID mode - only need to do this if we
* were truly frobbing a real device.
*/
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
pr_debug("MTD %s(): return to ID mode\n", __func__ );
if (cfi->addr_unlock1) {
cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
@ -2167,13 +2161,11 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
cfi->mfr = jedec_read_mfr(map, base, cfi);
cfi->id = jedec_read_id(map, base, cfi);
DEBUG(MTD_DEBUG_LEVEL3,
"Search for id:(%02x %02x) interleave(%d) type(%d)\n",
pr_debug("Search for id:(%02x %02x) interleave(%d) type(%d)\n",
cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
for (i = 0; i < ARRAY_SIZE(jedec_table); i++) {
if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
DEBUG( MTD_DEBUG_LEVEL3,
"MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
pr_debug("MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
__func__, cfi->mfr, cfi->id,
cfi->addr_unlock1, cfi->addr_unlock2 );
if (!cfi_jedec_setup(map, cfi, i))

View File

@ -189,10 +189,7 @@ static struct mtd_partition * newpart(char *s,
extra_mem_size;
parts = kzalloc(alloc_size, GFP_KERNEL);
if (!parts)
{
printk(KERN_ERR ERRP "out of memory\n");
return NULL;
}
extra_mem = (unsigned char *)(parts + *num_parts);
}
/* enter this partition (offset will be calculated later if it is zero at this point) */
@ -317,8 +314,8 @@ static int mtdpart_setup_real(char *s)
* the first one in the chain if a NULL mtd_id is passed in.
*/
static int parse_cmdline_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
unsigned long origin)
struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
unsigned long offset;
int i;

View File

@ -249,6 +249,16 @@ config MTD_DOC2001PLUS
under "NAND Flash Device Drivers" (currently that driver does not
support all Millennium Plus devices).
config MTD_DOCG3
tristate "M-Systems Disk-On-Chip G3"
---help---
This provides an MTD device driver for the M-Systems DiskOnChip
G3 devices.
The driver provides access to G3 DiskOnChip, distributed by
M-Systems and now Sandisk. The support is very experimental,
and doesn't give access to any write operations.
config MTD_DOCPROBE
tristate
select MTD_DOCECC
@ -268,8 +278,7 @@ config MTD_DOCPROBE_ADVANCED
config MTD_DOCPROBE_ADDRESS
hex "Physical address of DiskOnChip" if MTD_DOCPROBE_ADVANCED
depends on MTD_DOCPROBE
default "0x0000" if MTD_DOCPROBE_ADVANCED
default "0" if !MTD_DOCPROBE_ADVANCED
default "0x0"
---help---
By default, the probe for DiskOnChip devices will look for a
DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000.

View File

@ -5,6 +5,7 @@
obj-$(CONFIG_MTD_DOC2000) += doc2000.o
obj-$(CONFIG_MTD_DOC2001) += doc2001.o
obj-$(CONFIG_MTD_DOC2001PLUS) += doc2001plus.o
obj-$(CONFIG_MTD_DOCG3) += docg3.o
obj-$(CONFIG_MTD_DOCPROBE) += docprobe.o
obj-$(CONFIG_MTD_DOCECC) += docecc.o
obj-$(CONFIG_MTD_SLRAM) += slram.o
@ -17,3 +18,5 @@ obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
obj-$(CONFIG_MTD_M25P80) += m25p80.o
obj-$(CONFIG_MTD_SST25L) += sst25l.o
CFLAGS_docg3.o += -I$(src)

View File

@ -82,8 +82,7 @@ static int _DoC_WaitReady(struct DiskOnChip *doc)
void __iomem *docptr = doc->virtadr;
unsigned long timeo = jiffies + (HZ * 10);
DEBUG(MTD_DEBUG_LEVEL3,
"_DoC_WaitReady called for out-of-line wait\n");
pr_debug("_DoC_WaitReady called for out-of-line wait\n");
/* Out-of-line routine to wait for chip response */
while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
@ -92,7 +91,7 @@ static int _DoC_WaitReady(struct DiskOnChip *doc)
DoC_Delay(doc, 2);
if (time_after(jiffies, timeo)) {
DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
pr_debug("_DoC_WaitReady timed out.\n");
return -EIO;
}
udelay(1);
@ -323,8 +322,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
/* Reset the chip */
if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
DEBUG(MTD_DEBUG_LEVEL2,
"DoC_Command (reset) for %d,%d returned true\n",
pr_debug("DoC_Command (reset) for %d,%d returned true\n",
floor, chip);
return 0;
}
@ -332,8 +330,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
/* Read the NAND chip ID: 1. Send ReadID command */
if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
DEBUG(MTD_DEBUG_LEVEL2,
"DoC_Command (ReadID) for %d,%d returned true\n",
pr_debug("DoC_Command (ReadID) for %d,%d returned true\n",
floor, chip);
return 0;
}
@ -699,7 +696,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
#ifdef ECC_DEBUG
printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from);
#endif
/* Read the ECC syndrom through the DiskOnChip ECC
/* Read the ECC syndrome through the DiskOnChip ECC
logic. These syndrome will be all ZERO when there
is no error */
for (i = 0; i < 6; i++) {
@ -930,7 +927,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
uint8_t *buf = ops->oobbuf;
size_t len = ops->len;
BUG_ON(ops->mode != MTD_OOB_PLACE);
BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
ofs += ops->ooboffs;
@ -1094,7 +1091,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
struct DiskOnChip *this = mtd->priv;
int ret;
BUG_ON(ops->mode != MTD_OOB_PLACE);
BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
mutex_lock(&this->lock);
ret = doc_write_oob_nolock(mtd, ofs + ops->ooboffs, ops->len,

View File

@ -55,15 +55,14 @@ static int _DoC_WaitReady(void __iomem * docptr)
{
unsigned short c = 0xffff;
DEBUG(MTD_DEBUG_LEVEL3,
"_DoC_WaitReady called for out-of-line wait\n");
pr_debug("_DoC_WaitReady called for out-of-line wait\n");
/* Out-of-line routine to wait for chip response */
while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
;
if (c == 0)
DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
pr_debug("_DoC_WaitReady timed out.\n");
return (c == 0);
}
@ -464,7 +463,7 @@ static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
#ifdef ECC_DEBUG
printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
#endif
/* Read the ECC syndrom through the DiskOnChip ECC logic.
/* Read the ECC syndrome through the DiskOnChip ECC logic.
These syndrome will be all ZERO when there is no error */
for (i = 0; i < 6; i++) {
syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
@ -632,7 +631,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
uint8_t *buf = ops->oobbuf;
size_t len = ops->len;
BUG_ON(ops->mode != MTD_OOB_PLACE);
BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
ofs += ops->ooboffs;
@ -690,7 +689,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
uint8_t *buf = ops->oobbuf;
size_t len = ops->len;
BUG_ON(ops->mode != MTD_OOB_PLACE);
BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
ofs += ops->ooboffs;

View File

@ -61,15 +61,14 @@ static int _DoC_WaitReady(void __iomem * docptr)
{
unsigned int c = 0xffff;
DEBUG(MTD_DEBUG_LEVEL3,
"_DoC_WaitReady called for out-of-line wait\n");
pr_debug("_DoC_WaitReady called for out-of-line wait\n");
/* Out-of-line routine to wait for chip response */
while (((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) && --c)
;
if (c == 0)
DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
pr_debug("_DoC_WaitReady timed out.\n");
return (c == 0);
}
@ -655,7 +654,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
#ifdef ECC_DEBUG
printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
#endif
/* Read the ECC syndrom through the DiskOnChip ECC logic.
/* Read the ECC syndrome through the DiskOnChip ECC logic.
These syndrome will be all ZERO when there is no error */
for (i = 0; i < 6; i++)
syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
@ -835,7 +834,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
uint8_t *buf = ops->oobbuf;
size_t len = ops->len;
BUG_ON(ops->mode != MTD_OOB_PLACE);
BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
ofs += ops->ooboffs;
@ -920,7 +919,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
uint8_t *buf = ops->oobbuf;
size_t len = ops->len;
BUG_ON(ops->mode != MTD_OOB_PLACE);
BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
ofs += ops->ooboffs;

View File

@ -2,7 +2,7 @@
* ECC algorithm for M-systems disk on chip. We use the excellent Reed
* Solmon code of Phil Karn (karn@ka9q.ampr.org) available under the
* GNU GPL License. The rest is simply to convert the disk on chip
* syndrom into a standard syndom.
* syndrome into a standard syndome.
*
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A.

1114
drivers/mtd/devices/docg3.c Normal file

File diff suppressed because it is too large Load Diff

297
drivers/mtd/devices/docg3.h Normal file
View File

@ -0,0 +1,297 @@
/*
* Handles the M-Systems DiskOnChip G3 chip
*
* Copyright (C) 2011 Robert Jarzmik
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _MTD_DOCG3_H
#define _MTD_DOCG3_H
/*
* Flash memory areas :
* - 0x0000 .. 0x07ff : IPL
* - 0x0800 .. 0x0fff : Data area
* - 0x1000 .. 0x17ff : Registers
* - 0x1800 .. 0x1fff : Unknown
*/
#define DOC_IOSPACE_IPL 0x0000
#define DOC_IOSPACE_DATA 0x0800
#define DOC_IOSPACE_SIZE 0x2000
/*
* DOC G3 layout and adressing scheme
* A page address for the block "b", plane "P" and page "p":
* address = [bbbb bPpp pppp]
*/
#define DOC_ADDR_PAGE_MASK 0x3f
#define DOC_ADDR_BLOCK_SHIFT 6
#define DOC_LAYOUT_NBPLANES 2
#define DOC_LAYOUT_PAGES_PER_BLOCK 64
#define DOC_LAYOUT_PAGE_SIZE 512
#define DOC_LAYOUT_OOB_SIZE 16
#define DOC_LAYOUT_WEAR_SIZE 8
#define DOC_LAYOUT_PAGE_OOB_SIZE \
(DOC_LAYOUT_PAGE_SIZE + DOC_LAYOUT_OOB_SIZE)
#define DOC_LAYOUT_WEAR_OFFSET (DOC_LAYOUT_PAGE_OOB_SIZE * 2)
#define DOC_LAYOUT_BLOCK_SIZE \
(DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_PAGE_SIZE)
#define DOC_ECC_BCH_SIZE 7
#define DOC_ECC_BCH_COVERED_BYTES \
(DOC_LAYOUT_PAGE_SIZE + DOC_LAYOUT_OOB_PAGEINFO_SZ + \
DOC_LAYOUT_OOB_HAMMING_SZ + DOC_LAYOUT_OOB_BCH_SZ)
/*
* Blocks distribution
*/
#define DOC_LAYOUT_BLOCK_BBT 0
#define DOC_LAYOUT_BLOCK_OTP 0
#define DOC_LAYOUT_BLOCK_FIRST_DATA 6
#define DOC_LAYOUT_PAGE_BBT 4
/*
* Extra page OOB (16 bytes wide) layout
*/
#define DOC_LAYOUT_OOB_PAGEINFO_OFS 0
#define DOC_LAYOUT_OOB_HAMMING_OFS 7
#define DOC_LAYOUT_OOB_BCH_OFS 8
#define DOC_LAYOUT_OOB_UNUSED_OFS 15
#define DOC_LAYOUT_OOB_PAGEINFO_SZ 7
#define DOC_LAYOUT_OOB_HAMMING_SZ 1
#define DOC_LAYOUT_OOB_BCH_SZ 7
#define DOC_LAYOUT_OOB_UNUSED_SZ 1
#define DOC_CHIPID_G3 0x200
#define DOC_ERASE_MARK 0xaa
/*
* Flash registers
*/
#define DOC_CHIPID 0x1000
#define DOC_TEST 0x1004
#define DOC_BUSLOCK 0x1006
#define DOC_ENDIANCONTROL 0x1008
#define DOC_DEVICESELECT 0x100a
#define DOC_ASICMODE 0x100c
#define DOC_CONFIGURATION 0x100e
#define DOC_INTERRUPTCONTROL 0x1010
#define DOC_READADDRESS 0x101a
#define DOC_DATAEND 0x101e
#define DOC_INTERRUPTSTATUS 0x1020
#define DOC_FLASHSEQUENCE 0x1032
#define DOC_FLASHCOMMAND 0x1034
#define DOC_FLASHADDRESS 0x1036
#define DOC_FLASHCONTROL 0x1038
#define DOC_NOP 0x103e
#define DOC_ECCCONF0 0x1040
#define DOC_ECCCONF1 0x1042
#define DOC_ECCPRESET 0x1044
#define DOC_HAMMINGPARITY 0x1046
#define DOC_BCH_SYNDROM(idx) (0x1048 + (idx << 1))
#define DOC_PROTECTION 0x1056
#define DOC_DPS0_ADDRLOW 0x1060
#define DOC_DPS0_ADDRHIGH 0x1062
#define DOC_DPS1_ADDRLOW 0x1064
#define DOC_DPS1_ADDRHIGH 0x1066
#define DOC_DPS0_STATUS 0x106c
#define DOC_DPS1_STATUS 0x106e
#define DOC_ASICMODECONFIRM 0x1072
#define DOC_CHIPID_INV 0x1074
/*
* Flash sequences
* A sequence is preset before one or more commands are input to the chip.
*/
#define DOC_SEQ_RESET 0x00
#define DOC_SEQ_PAGE_SIZE_532 0x03
#define DOC_SEQ_SET_MODE 0x09
#define DOC_SEQ_READ 0x12
#define DOC_SEQ_SET_PLANE1 0x0e
#define DOC_SEQ_SET_PLANE2 0x10
#define DOC_SEQ_PAGE_SETUP 0x1d
/*
* Flash commands
*/
#define DOC_CMD_READ_PLANE1 0x00
#define DOC_CMD_SET_ADDR_READ 0x05
#define DOC_CMD_READ_ALL_PLANES 0x30
#define DOC_CMD_READ_PLANE2 0x50
#define DOC_CMD_READ_FLASH 0xe0
#define DOC_CMD_PAGE_SIZE_532 0x3c
#define DOC_CMD_PROG_BLOCK_ADDR 0x60
#define DOC_CMD_PROG_CYCLE1 0x80
#define DOC_CMD_PROG_CYCLE2 0x10
#define DOC_CMD_ERASECYCLE2 0xd0
#define DOC_CMD_RELIABLE_MODE 0x22
#define DOC_CMD_FAST_MODE 0xa2
#define DOC_CMD_RESET 0xff
/*
* Flash register : DOC_FLASHCONTROL
*/
#define DOC_CTRL_VIOLATION 0x20
#define DOC_CTRL_CE 0x10
#define DOC_CTRL_UNKNOWN_BITS 0x08
#define DOC_CTRL_PROTECTION_ERROR 0x04
#define DOC_CTRL_SEQUENCE_ERROR 0x02
#define DOC_CTRL_FLASHREADY 0x01
/*
* Flash register : DOC_ASICMODE
*/
#define DOC_ASICMODE_RESET 0x00
#define DOC_ASICMODE_NORMAL 0x01
#define DOC_ASICMODE_POWERDOWN 0x02
#define DOC_ASICMODE_MDWREN 0x04
#define DOC_ASICMODE_BDETCT_RESET 0x08
#define DOC_ASICMODE_RSTIN_RESET 0x10
#define DOC_ASICMODE_RAM_WE 0x20
/*
* Flash register : DOC_ECCCONF0
*/
#define DOC_ECCCONF0_READ_MODE 0x8000
#define DOC_ECCCONF0_AUTO_ECC_ENABLE 0x4000
#define DOC_ECCCONF0_HAMMING_ENABLE 0x1000
#define DOC_ECCCONF0_BCH_ENABLE 0x0800
#define DOC_ECCCONF0_DATA_BYTES_MASK 0x07ff
/*
* Flash register : DOC_ECCCONF1
*/
#define DOC_ECCCONF1_BCH_SYNDROM_ERR 0x80
#define DOC_ECCCONF1_UNKOWN1 0x40
#define DOC_ECCCONF1_UNKOWN2 0x20
#define DOC_ECCCONF1_UNKOWN3 0x10
#define DOC_ECCCONF1_HAMMING_BITS_MASK 0x0f
/*
* Flash register : DOC_PROTECTION
*/
#define DOC_PROTECT_FOUNDRY_OTP_LOCK 0x01
#define DOC_PROTECT_CUSTOMER_OTP_LOCK 0x02
#define DOC_PROTECT_LOCK_INPUT 0x04
#define DOC_PROTECT_STICKY_LOCK 0x08
#define DOC_PROTECT_PROTECTION_ENABLED 0x10
#define DOC_PROTECT_IPL_DOWNLOAD_LOCK 0x20
#define DOC_PROTECT_PROTECTION_ERROR 0x80
/*
* Flash register : DOC_DPS0_STATUS and DOC_DPS1_STATUS
*/
#define DOC_DPS_OTP_PROTECTED 0x01
#define DOC_DPS_READ_PROTECTED 0x02
#define DOC_DPS_WRITE_PROTECTED 0x04
#define DOC_DPS_HW_LOCK_ENABLED 0x08
#define DOC_DPS_KEY_OK 0x80
/*
* Flash register : DOC_CONFIGURATION
*/
#define DOC_CONF_IF_CFG 0x80
#define DOC_CONF_MAX_ID_MASK 0x30
#define DOC_CONF_VCCQ_3V 0x01
/*
* Flash register : DOC_READADDRESS
*/
#define DOC_READADDR_INC 0x8000
#define DOC_READADDR_ONE_BYTE 0x4000
#define DOC_READADDR_ADDR_MASK 0x1fff
/**
* struct docg3 - DiskOnChip driver private data
* @dev: the device currently under control
* @base: mapped IO space
* @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3)
* @if_cfg: if true, reads are on 16bits, else reads are on 8bits
* @bbt: bad block table cache
* @debugfs_root: debugfs root node
*/
struct docg3 {
struct device *dev;
void __iomem *base;
unsigned int device_id:4;
unsigned int if_cfg:1;
int max_block;
u8 *bbt;
struct dentry *debugfs_root;
};
#define doc_err(fmt, arg...) dev_err(docg3->dev, (fmt), ## arg)
#define doc_info(fmt, arg...) dev_info(docg3->dev, (fmt), ## arg)
#define doc_dbg(fmt, arg...) dev_dbg(docg3->dev, (fmt), ## arg)
#define doc_vdbg(fmt, arg...) dev_vdbg(docg3->dev, (fmt), ## arg)
#define DEBUGFS_RO_ATTR(name, show_fct) \
static int name##_open(struct inode *inode, struct file *file) \
{ return single_open(file, show_fct, inode->i_private); } \
static const struct file_operations name##_fops = { \
.owner = THIS_MODULE, \
.open = name##_open, \
.llseek = seq_lseek, \
.read = seq_read, \
.release = single_release \
};
#endif
/*
* Trace events part
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM docg3
#if !defined(_MTD_DOCG3_TRACE) || defined(TRACE_HEADER_MULTI_READ)
#define _MTD_DOCG3_TRACE
#include <linux/tracepoint.h>
TRACE_EVENT(docg3_io,
TP_PROTO(int op, int width, u16 reg, int val),
TP_ARGS(op, width, reg, val),
TP_STRUCT__entry(
__field(int, op)
__field(unsigned char, width)
__field(u16, reg)
__field(int, val)),
TP_fast_assign(
__entry->op = op;
__entry->width = width;
__entry->reg = reg;
__entry->val = val;),
TP_printk("docg3: %s%02d reg=%04x, val=%04x",
__entry->op ? "write" : "read", __entry->width,
__entry->reg, __entry->val)
);
#endif
/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_PATH .
#define TRACE_INCLUDE_FILE docg3
#include <trace/define_trace.h>

View File

@ -50,11 +50,6 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/doc2000.h>
/* Where to look for the devices? */
#ifndef CONFIG_MTD_DOCPROBE_ADDRESS
#define CONFIG_MTD_DOCPROBE_ADDRESS 0
#endif
static unsigned long doc_config_location = CONFIG_MTD_DOCPROBE_ADDRESS;
module_param(doc_config_location, ulong, 0);

View File

@ -34,9 +34,6 @@
/* debugging */
//#define LART_DEBUG
/* partition support */
#define HAVE_PARTITIONS
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
@ -44,9 +41,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mtd/mtd.h>
#ifdef HAVE_PARTITIONS
#include <linux/mtd/partitions.h>
#endif
#ifndef CONFIG_SA1100_LART
#error This is for LART architecture only
@ -598,7 +593,6 @@ static struct mtd_erase_region_info erase_regions[] = {
}
};
#ifdef HAVE_PARTITIONS
static struct mtd_partition lart_partitions[] = {
/* blob */
{
@ -619,7 +613,7 @@ static struct mtd_partition lart_partitions[] = {
.size = INITRD_LEN, /* MTDPART_SIZ_FULL */
}
};
#endif
#define NUM_PARTITIONS ARRAY_SIZE(lart_partitions)
static int __init lart_flash_init (void)
{
@ -668,7 +662,6 @@ static int __init lart_flash_init (void)
result,mtd.eraseregions[result].erasesize,mtd.eraseregions[result].erasesize / 1024,
result,mtd.eraseregions[result].numblocks);
#ifdef HAVE_PARTITIONS
printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions));
for (result = 0; result < ARRAY_SIZE(lart_partitions); result++)
@ -681,25 +674,16 @@ static int __init lart_flash_init (void)
result,lart_partitions[result].offset,
result,lart_partitions[result].size,lart_partitions[result].size / 1024);
#endif
#endif
#ifndef HAVE_PARTITIONS
result = mtd_device_register(&mtd, NULL, 0);
#else
result = mtd_device_register(&mtd, lart_partitions,
ARRAY_SIZE(lart_partitions));
#endif
return (result);
}
static void __exit lart_flash_exit (void)
{
#ifndef HAVE_PARTITIONS
mtd_device_unregister(&mtd);
#else
mtd_device_unregister(&mtd);
#endif
}
module_init (lart_flash_init);

View File

@ -30,6 +30,7 @@
#include <linux/mtd/cfi.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/of_platform.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
@ -88,7 +89,6 @@ struct m25p {
struct spi_device *spi;
struct mutex lock;
struct mtd_info mtd;
unsigned partitioned:1;
u16 page_size;
u16 addr_width;
u8 erase_opcode;
@ -209,9 +209,8 @@ static int wait_till_ready(struct m25p *flash)
*/
static int erase_chip(struct m25p *flash)
{
DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %lldKiB\n",
dev_name(&flash->spi->dev), __func__,
(long long)(flash->mtd.size >> 10));
pr_debug("%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))
@ -250,9 +249,8 @@ static int m25p_cmdsz(struct m25p *flash)
*/
static int erase_sector(struct m25p *flash, u32 offset)
{
DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB at 0x%08x\n",
dev_name(&flash->spi->dev), __func__,
flash->mtd.erasesize / 1024, offset);
pr_debug("%s: %s %dKiB at 0x%08x\n", dev_name(&flash->spi->dev),
__func__, flash->mtd.erasesize / 1024, offset);
/* Wait until finished previous write command. */
if (wait_till_ready(flash))
@ -286,9 +284,9 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
u32 addr,len;
uint32_t rem;
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);
pr_debug("%s: %s at 0x%llx, len %lld\n", dev_name(&flash->spi->dev),
__func__, (long long)instr->addr,
(long long)instr->len);
/* sanity checks */
if (instr->addr + instr->len > flash->mtd.size)
@ -348,9 +346,8 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
struct spi_transfer t[2];
struct spi_message m;
DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
dev_name(&flash->spi->dev), __func__, "from",
(u32)from, len);
pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
__func__, (u32)from, len);
/* sanity checks */
if (!len)
@ -417,9 +414,8 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
struct spi_transfer t[2];
struct spi_message m;
DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
dev_name(&flash->spi->dev), __func__, "to",
(u32)to, len);
pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
__func__, (u32)to, len);
*retlen = 0;
@ -510,9 +506,8 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t actual;
int cmd_sz, ret;
DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
dev_name(&flash->spi->dev), __func__, "to",
(u32)to, len);
pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
__func__, (u32)to, len);
*retlen = 0;
@ -661,6 +656,7 @@ static const struct spi_device_id m25p_ids[] = {
{ "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) },
{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) },
{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) },
{ "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
{ "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) },
@ -671,6 +667,7 @@ static const struct spi_device_id m25p_ids[] = {
/* EON -- en25xxx */
{ "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) },
{ "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
{ "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) },
{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
/* Intel/Numonyx -- xxxs33b */
@ -788,8 +785,8 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
*/
tmp = spi_write_then_read(spi, &code, 1, id, 5);
if (tmp < 0) {
DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
dev_name(&spi->dev), tmp);
pr_debug("%s: error %d reading JEDEC ID\n",
dev_name(&spi->dev), tmp);
return ERR_PTR(tmp);
}
jedec = id[0];
@ -825,8 +822,12 @@ static int __devinit m25p_probe(struct spi_device *spi)
struct m25p *flash;
struct flash_info *info;
unsigned i;
struct mtd_partition *parts = NULL;
int nr_parts = 0;
struct mtd_part_parser_data ppdata;
#ifdef CONFIG_MTD_OF_PARTS
if (!of_device_is_available(spi->dev.of_node))
return -ENODEV;
#endif
/* Platform data helps sort out which chip type we have, as
* well as how this board partitions it. If we don't have
@ -928,6 +929,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
if (info->flags & M25P_NO_ERASE)
flash->mtd.flags |= MTD_NO_ERASE;
ppdata.of_node = spi->dev.of_node;
flash->mtd.dev.parent = &spi->dev;
flash->page_size = info->page_size;
@ -945,8 +947,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name,
(long long)flash->mtd.size >> 10);
DEBUG(MTD_DEBUG_LEVEL2,
"mtd .name = %s, .size = 0x%llx (%lldMiB) "
pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
flash->mtd.name,
(long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
@ -955,8 +956,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
if (flash->mtd.numeraseregions)
for (i = 0; i < flash->mtd.numeraseregions; i++)
DEBUG(MTD_DEBUG_LEVEL2,
"mtd.eraseregions[%d] = { .offset = 0x%llx, "
pr_debug("mtd.eraseregions[%d] = { .offset = 0x%llx, "
".erasesize = 0x%.8x (%uKiB), "
".numblocks = %d }\n",
i, (long long)flash->mtd.eraseregions[i].offset,
@ -968,41 +968,9 @@ static int __devinit m25p_probe(struct spi_device *spi)
/* partitions should match sector boundaries; and it may be good to
* use readonly partitions for writeprotected sectors (BP2..BP0).
*/
if (mtd_has_cmdlinepart()) {
static const char *part_probes[]
= { "cmdlinepart", NULL, };
nr_parts = parse_mtd_partitions(&flash->mtd,
part_probes, &parts, 0);
}
if (nr_parts <= 0 && data && data->parts) {
parts = data->parts;
nr_parts = data->nr_parts;
}
#ifdef CONFIG_MTD_OF_PARTS
if (nr_parts <= 0 && spi->dev.of_node) {
nr_parts = of_mtd_parse_partitions(&spi->dev,
spi->dev.of_node, &parts);
}
#endif
if (nr_parts > 0) {
for (i = 0; i < nr_parts; i++) {
DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
"{.name = %s, .offset = 0x%llx, "
".size = 0x%llx (%lldKiB) }\n",
i, parts[i].name,
(long long)parts[i].offset,
(long long)parts[i].size,
(long long)(parts[i].size >> 10));
}
flash->partitioned = 1;
}
return mtd_device_register(&flash->mtd, parts, nr_parts) == 1 ?
-ENODEV : 0;
return mtd_device_parse_register(&flash->mtd, NULL, &ppdata,
data ? data->parts : NULL,
data ? data->nr_parts : 0);
}

View File

@ -17,6 +17,8 @@
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/math64.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
@ -24,7 +26,6 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
/*
* DataFlash is a kind of SPI flash. Most AT45 chips have two buffers in
* each chip, which may be used for double buffered I/O; but this driver
@ -98,6 +99,16 @@ struct dataflash {
struct mtd_info mtd;
};
#ifdef CONFIG_OF
static const struct of_device_id dataflash_dt_ids[] = {
{ .compatible = "atmel,at45", },
{ .compatible = "atmel,dataflash", },
{ /* sentinel */ }
};
#else
#define dataflash_dt_ids NULL
#endif
/* ......................................................................... */
/*
@ -122,7 +133,7 @@ static int dataflash_waitready(struct spi_device *spi)
for (;;) {
status = dataflash_status(spi);
if (status < 0) {
DEBUG(MTD_DEBUG_LEVEL1, "%s: status %d?\n",
pr_debug("%s: status %d?\n",
dev_name(&spi->dev), status);
status = 0;
}
@ -149,7 +160,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
uint8_t *command;
uint32_t rem;
DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%llx len 0x%llx\n",
pr_debug("%s: erase addr=0x%llx len 0x%llx\n",
dev_name(&spi->dev), (long long)instr->addr,
(long long)instr->len);
@ -187,7 +198,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
command[2] = (uint8_t)(pageaddr >> 8);
command[3] = 0;
DEBUG(MTD_DEBUG_LEVEL3, "ERASE %s: (%x) %x %x %x [%i]\n",
pr_debug("ERASE %s: (%x) %x %x %x [%i]\n",
do_block ? "block" : "page",
command[0], command[1], command[2], command[3],
pageaddr);
@ -238,8 +249,8 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
uint8_t *command;
int status;
DEBUG(MTD_DEBUG_LEVEL2, "%s: read 0x%x..0x%x\n",
dev_name(&priv->spi->dev), (unsigned)from, (unsigned)(from + len));
pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev),
(unsigned)from, (unsigned)(from + len));
*retlen = 0;
@ -255,7 +266,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
command = priv->command;
DEBUG(MTD_DEBUG_LEVEL3, "READ: (%x) %x %x %x\n",
pr_debug("READ: (%x) %x %x %x\n",
command[0], command[1], command[2], command[3]);
spi_message_init(&msg);
@ -287,7 +298,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
*retlen = msg.actual_length - 8;
status = 0;
} else
DEBUG(MTD_DEBUG_LEVEL1, "%s: read %x..%x --> %d\n",
pr_debug("%s: read %x..%x --> %d\n",
dev_name(&priv->spi->dev),
(unsigned)from, (unsigned)(from + len),
status);
@ -314,7 +325,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
int status = -EINVAL;
uint8_t *command;
DEBUG(MTD_DEBUG_LEVEL2, "%s: write 0x%x..0x%x\n",
pr_debug("%s: write 0x%x..0x%x\n",
dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len));
*retlen = 0;
@ -340,7 +351,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
mutex_lock(&priv->lock);
while (remaining > 0) {
DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n",
pr_debug("write @ %i:%i len=%i\n",
pageaddr, offset, writelen);
/* REVISIT:
@ -368,12 +379,12 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
command[2] = (addr & 0x0000FF00) >> 8;
command[3] = 0;
DEBUG(MTD_DEBUG_LEVEL3, "TRANSFER: (%x) %x %x %x\n",
pr_debug("TRANSFER: (%x) %x %x %x\n",
command[0], command[1], command[2], command[3]);
status = spi_sync(spi, &msg);
if (status < 0)
DEBUG(MTD_DEBUG_LEVEL1, "%s: xfer %u -> %d \n",
pr_debug("%s: xfer %u -> %d\n",
dev_name(&spi->dev), addr, status);
(void) dataflash_waitready(priv->spi);
@ -386,7 +397,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
command[2] = (addr & 0x0000FF00) >> 8;
command[3] = (addr & 0x000000FF);
DEBUG(MTD_DEBUG_LEVEL3, "PROGRAM: (%x) %x %x %x\n",
pr_debug("PROGRAM: (%x) %x %x %x\n",
command[0], command[1], command[2], command[3]);
x[1].tx_buf = writebuf;
@ -395,7 +406,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
status = spi_sync(spi, &msg);
spi_transfer_del(x + 1);
if (status < 0)
DEBUG(MTD_DEBUG_LEVEL1, "%s: pgm %u/%u -> %d \n",
pr_debug("%s: pgm %u/%u -> %d\n",
dev_name(&spi->dev), addr, writelen, status);
(void) dataflash_waitready(priv->spi);
@ -410,12 +421,12 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
command[2] = (addr & 0x0000FF00) >> 8;
command[3] = 0;
DEBUG(MTD_DEBUG_LEVEL3, "COMPARE: (%x) %x %x %x\n",
pr_debug("COMPARE: (%x) %x %x %x\n",
command[0], command[1], command[2], command[3]);
status = spi_sync(spi, &msg);
if (status < 0)
DEBUG(MTD_DEBUG_LEVEL1, "%s: compare %u -> %d \n",
pr_debug("%s: compare %u -> %d\n",
dev_name(&spi->dev), addr, status);
status = dataflash_waitready(priv->spi);
@ -634,11 +645,10 @@ add_dataflash_otp(struct spi_device *spi, char *name,
{
struct dataflash *priv;
struct mtd_info *device;
struct mtd_part_parser_data ppdata;
struct flash_platform_data *pdata = spi->dev.platform_data;
char *otp_tag = "";
int err = 0;
struct mtd_partition *parts;
int nr_parts = 0;
priv = kzalloc(sizeof *priv, GFP_KERNEL);
if (!priv)
@ -677,28 +687,11 @@ add_dataflash_otp(struct spi_device *spi, char *name,
pagesize, otp_tag);
dev_set_drvdata(&spi->dev, priv);
if (mtd_has_cmdlinepart()) {
static const char *part_probes[] = { "cmdlinepart", NULL, };
ppdata.of_node = spi->dev.of_node;
err = mtd_device_parse_register(device, NULL, &ppdata,
pdata ? pdata->parts : NULL,
pdata ? pdata->nr_parts : 0);
nr_parts = parse_mtd_partitions(device, part_probes, &parts,
0);
}
if (nr_parts <= 0 && pdata && pdata->parts) {
parts = pdata->parts;
nr_parts = pdata->nr_parts;
}
if (nr_parts > 0) {
priv->partitioned = 1;
err = mtd_device_register(device, parts, nr_parts);
goto out;
}
if (mtd_device_register(device, NULL, 0) == 1)
err = -ENODEV;
out:
if (!err)
return 0;
@ -787,7 +780,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
*/
tmp = spi_write_then_read(spi, &code, 1, id, 3);
if (tmp < 0) {
DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
pr_debug("%s: error %d reading JEDEC ID\n",
dev_name(&spi->dev), tmp);
return ERR_PTR(tmp);
}
@ -804,7 +797,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
tmp < ARRAY_SIZE(dataflash_data);
tmp++, info++) {
if (info->jedec_id == jedec) {
DEBUG(MTD_DEBUG_LEVEL1, "%s: OTP, sector protect%s\n",
pr_debug("%s: OTP, sector protect%s\n",
dev_name(&spi->dev),
(info->flags & SUP_POW2PS)
? ", binary pagesize" : ""
@ -812,8 +805,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
if (info->flags & SUP_POW2PS) {
status = dataflash_status(spi);
if (status < 0) {
DEBUG(MTD_DEBUG_LEVEL1,
"%s: status error %d\n",
pr_debug("%s: status error %d\n",
dev_name(&spi->dev), status);
return ERR_PTR(status);
}
@ -878,7 +870,7 @@ static int __devinit dataflash_probe(struct spi_device *spi)
*/
status = dataflash_status(spi);
if (status <= 0 || status == 0xff) {
DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n",
pr_debug("%s: status error %d\n",
dev_name(&spi->dev), status);
if (status == 0 || status == 0xff)
status = -ENODEV;
@ -914,14 +906,14 @@ static int __devinit dataflash_probe(struct spi_device *spi)
break;
/* obsolete AT45DB1282 not (yet?) supported */
default:
DEBUG(MTD_DEBUG_LEVEL1, "%s: unsupported device (%x)\n",
dev_name(&spi->dev), status & 0x3c);
pr_debug("%s: unsupported device (%x)\n", dev_name(&spi->dev),
status & 0x3c);
status = -ENODEV;
}
if (status < 0)
DEBUG(MTD_DEBUG_LEVEL1, "%s: add_dataflash --> %d\n",
dev_name(&spi->dev), status);
pr_debug("%s: add_dataflash --> %d\n", dev_name(&spi->dev),
status);
return status;
}
@ -931,7 +923,7 @@ static int __devexit dataflash_remove(struct spi_device *spi)
struct dataflash *flash = dev_get_drvdata(&spi->dev);
int status;
DEBUG(MTD_DEBUG_LEVEL1, "%s: remove\n", dev_name(&spi->dev));
pr_debug("%s: remove\n", dev_name(&spi->dev));
status = mtd_device_unregister(&flash->mtd);
if (status == 0) {
@ -946,6 +938,7 @@ static struct spi_driver dataflash_driver = {
.name = "mtd_dataflash",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
.of_match_table = dataflash_dt_ids,
},
.probe = dataflash_probe,

View File

@ -52,8 +52,6 @@ struct sst25l_flash {
struct spi_device *spi;
struct mutex lock;
struct mtd_info mtd;
int partitioned;
};
struct flash_info {
@ -381,8 +379,6 @@ static int __devinit sst25l_probe(struct spi_device *spi)
struct sst25l_flash *flash;
struct flash_platform_data *data;
int ret, i;
struct mtd_partition *parts = NULL;
int nr_parts = 0;
flash_info = sst25l_match_device(spi);
if (!flash_info)
@ -414,8 +410,7 @@ static int __devinit sst25l_probe(struct spi_device *spi)
dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name,
(long long)flash->mtd.size >> 10);
DEBUG(MTD_DEBUG_LEVEL2,
"mtd .name = %s, .size = 0x%llx (%lldMiB) "
pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
flash->mtd.name,
(long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
@ -423,37 +418,10 @@ static int __devinit sst25l_probe(struct spi_device *spi)
flash->mtd.numeraseregions);
if (mtd_has_cmdlinepart()) {
static const char *part_probes[] = {"cmdlinepart", NULL};
nr_parts = parse_mtd_partitions(&flash->mtd,
part_probes,
&parts, 0);
}
if (nr_parts <= 0 && data && data->parts) {
parts = data->parts;
nr_parts = data->nr_parts;
}
if (nr_parts > 0) {
for (i = 0; i < nr_parts; i++) {
DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
"{.name = %s, .offset = 0x%llx, "
".size = 0x%llx (%lldKiB) }\n",
i, parts[i].name,
(long long)parts[i].offset,
(long long)parts[i].size,
(long long)(parts[i].size >> 10));
}
flash->partitioned = 1;
return mtd_device_register(&flash->mtd, parts,
nr_parts);
}
ret = mtd_device_register(&flash->mtd, NULL, 0);
if (ret == 1) {
ret = mtd_device_parse_register(&flash->mtd, NULL, 0,
data ? data->parts : NULL,
data ? data->nr_parts : 0);
if (ret) {
kfree(flash);
dev_set_drvdata(&spi->dev, NULL);
return -ENODEV;

View File

@ -339,7 +339,7 @@ static int erase_xfer(partition_t *part,
struct erase_info *erase;
xfer = &part->XferInfo[xfernum];
DEBUG(1, "ftl_cs: erasing xfer unit at 0x%x\n", xfer->Offset);
pr_debug("ftl_cs: erasing xfer unit at 0x%x\n", xfer->Offset);
xfer->state = XFER_ERASING;
/* Is there a free erase slot? Always in MTD. */
@ -415,7 +415,7 @@ static int prepare_xfer(partition_t *part, int i)
xfer = &part->XferInfo[i];
xfer->state = XFER_FAILED;
DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
pr_debug("ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
/* Write the transfer unit header */
header = part->header;
@ -476,7 +476,7 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
eun = &part->EUNInfo[srcunit];
xfer = &part->XferInfo[xferunit];
DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n",
pr_debug("ftl_cs: copying block 0x%x to 0x%x\n",
eun->Offset, xfer->Offset);
@ -598,7 +598,7 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
unit with the fewest erases, and usually pick the data unit with
the most deleted blocks. But with a small probability, pick the
oldest data unit instead. This means that we generally postpone
the next reclaimation as long as possible, but shuffle static
the next reclamation as long as possible, but shuffle static
stuff around a bit for wear leveling.
======================================================================*/
@ -609,8 +609,8 @@ static int reclaim_block(partition_t *part)
uint32_t best;
int queued, ret;
DEBUG(0, "ftl_cs: reclaiming space...\n");
DEBUG(3, "NumTransferUnits == %x\n", part->header.NumTransferUnits);
pr_debug("ftl_cs: reclaiming space...\n");
pr_debug("NumTransferUnits == %x\n", part->header.NumTransferUnits);
/* Pick the least erased transfer unit */
best = 0xffffffff; xfer = 0xffff;
do {
@ -618,22 +618,22 @@ static int reclaim_block(partition_t *part)
for (i = 0; i < part->header.NumTransferUnits; i++) {
int n=0;
if (part->XferInfo[i].state == XFER_UNKNOWN) {
DEBUG(3,"XferInfo[%d].state == XFER_UNKNOWN\n",i);
pr_debug("XferInfo[%d].state == XFER_UNKNOWN\n",i);
n=1;
erase_xfer(part, i);
}
if (part->XferInfo[i].state == XFER_ERASING) {
DEBUG(3,"XferInfo[%d].state == XFER_ERASING\n",i);
pr_debug("XferInfo[%d].state == XFER_ERASING\n",i);
n=1;
queued = 1;
}
else if (part->XferInfo[i].state == XFER_ERASED) {
DEBUG(3,"XferInfo[%d].state == XFER_ERASED\n",i);
pr_debug("XferInfo[%d].state == XFER_ERASED\n",i);
n=1;
prepare_xfer(part, i);
}
if (part->XferInfo[i].state == XFER_PREPARED) {
DEBUG(3,"XferInfo[%d].state == XFER_PREPARED\n",i);
pr_debug("XferInfo[%d].state == XFER_PREPARED\n",i);
n=1;
if (part->XferInfo[i].EraseCount <= best) {
best = part->XferInfo[i].EraseCount;
@ -641,12 +641,12 @@ static int reclaim_block(partition_t *part)
}
}
if (!n)
DEBUG(3,"XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
pr_debug("XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
}
if (xfer == 0xffff) {
if (queued) {
DEBUG(1, "ftl_cs: waiting for transfer "
pr_debug("ftl_cs: waiting for transfer "
"unit to be prepared...\n");
if (part->mbd.mtd->sync)
part->mbd.mtd->sync(part->mbd.mtd);
@ -656,7 +656,7 @@ static int reclaim_block(partition_t *part)
printk(KERN_NOTICE "ftl_cs: reclaim failed: no "
"suitable transfer units!\n");
else
DEBUG(1, "ftl_cs: reclaim failed: no "
pr_debug("ftl_cs: reclaim failed: no "
"suitable transfer units!\n");
return -EIO;
@ -666,7 +666,7 @@ static int reclaim_block(partition_t *part)
eun = 0;
if ((jiffies % shuffle_freq) == 0) {
DEBUG(1, "ftl_cs: recycling freshest block...\n");
pr_debug("ftl_cs: recycling freshest block...\n");
best = 0xffffffff;
for (i = 0; i < part->DataUnits; i++)
if (part->EUNInfo[i].EraseCount <= best) {
@ -686,7 +686,7 @@ static int reclaim_block(partition_t *part)
printk(KERN_NOTICE "ftl_cs: reclaim failed: "
"no free blocks!\n");
else
DEBUG(1,"ftl_cs: reclaim failed: "
pr_debug("ftl_cs: reclaim failed: "
"no free blocks!\n");
return -EIO;
@ -771,7 +771,7 @@ static uint32_t find_free(partition_t *part)
printk(KERN_NOTICE "ftl_cs: bad free list!\n");
return 0;
}
DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun);
pr_debug("ftl_cs: found free block at %d in %d\n", blk, eun);
return blk;
} /* find_free */
@ -791,7 +791,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
int ret;
size_t offset, retlen;
DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
pr_debug("ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
part, sector, nblocks);
if (!(part->state & FTL_FORMATTED)) {
printk(KERN_NOTICE "ftl_cs: bad partition\n");
@ -840,7 +840,7 @@ static int set_bam_entry(partition_t *part, uint32_t log_addr,
int ret;
size_t retlen, offset;
DEBUG(2, "ftl_cs: set_bam_entry(0x%p, 0x%x, 0x%x)\n",
pr_debug("ftl_cs: set_bam_entry(0x%p, 0x%x, 0x%x)\n",
part, log_addr, virt_addr);
bsize = 1 << part->header.EraseUnitSize;
eun = log_addr / bsize;
@ -905,7 +905,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
int ret;
size_t retlen, offset;
DEBUG(2, "ftl_cs: ftl_write(0x%p, %ld, %ld)\n",
pr_debug("ftl_cs: ftl_write(0x%p, %ld, %ld)\n",
part, sector, nblocks);
if (!(part->state & FTL_FORMATTED)) {
printk(KERN_NOTICE "ftl_cs: bad partition\n");
@ -1011,7 +1011,7 @@ static int ftl_discardsect(struct mtd_blktrans_dev *dev,
partition_t *part = (void *)dev;
uint32_t bsize = 1 << part->header.EraseUnitSize;
DEBUG(1, "FTL erase sector %ld for %d sectors\n",
pr_debug("FTL erase sector %ld for %d sectors\n",
sector, nr_sects);
while (nr_sects) {

View File

@ -63,14 +63,12 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
return;
}
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: add_mtd for %s\n", mtd->name);
pr_debug("INFTL: add_mtd for %s\n", mtd->name);
inftl = kzalloc(sizeof(*inftl), GFP_KERNEL);
if (!inftl) {
printk(KERN_WARNING "INFTL: Out of memory for data structures\n");
if (!inftl)
return;
}
inftl->mbd.mtd = mtd;
inftl->mbd.devnum = -1;
@ -133,7 +131,7 @@ static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
{
struct INFTLrecord *inftl = (void *)dev;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: remove_dev (i=%d)\n", dev->devnum);
pr_debug("INFTL: remove_dev (i=%d)\n", dev->devnum);
del_mtd_blktrans_dev(dev);
@ -154,7 +152,7 @@ int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
struct mtd_oob_ops ops;
int res;
ops.mode = MTD_OOB_PLACE;
ops.mode = MTD_OPS_PLACE_OOB;
ops.ooboffs = offs & (mtd->writesize - 1);
ops.ooblen = len;
ops.oobbuf = buf;
@ -174,7 +172,7 @@ int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
struct mtd_oob_ops ops;
int res;
ops.mode = MTD_OOB_PLACE;
ops.mode = MTD_OPS_PLACE_OOB;
ops.ooboffs = offs & (mtd->writesize - 1);
ops.ooblen = len;
ops.oobbuf = buf;
@ -194,7 +192,7 @@ static int inftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
struct mtd_oob_ops ops;
int res;
ops.mode = MTD_OOB_PLACE;
ops.mode = MTD_OPS_PLACE_OOB;
ops.ooboffs = offs;
ops.ooblen = mtd->oobsize;
ops.oobbuf = oob;
@ -215,16 +213,16 @@ static u16 INFTL_findfreeblock(struct INFTLrecord *inftl, int desperate)
u16 pot = inftl->LastFreeEUN;
int silly = inftl->nb_blocks;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findfreeblock(inftl=%p,"
"desperate=%d)\n", inftl, desperate);
pr_debug("INFTL: INFTL_findfreeblock(inftl=%p,desperate=%d)\n",
inftl, desperate);
/*
* Normally, we force a fold to happen before we run out of free
* blocks completely.
*/
if (!desperate && inftl->numfreeEUNs < 2) {
DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free "
"EUNs (%d)\n", inftl->numfreeEUNs);
pr_debug("INFTL: there are too few free EUNs (%d)\n",
inftl->numfreeEUNs);
return BLOCK_NIL;
}
@ -259,8 +257,8 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
struct inftl_oob oob;
size_t retlen;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_foldchain(inftl=%p,thisVUC=%d,"
"pending=%d)\n", inftl, thisVUC, pendingblock);
pr_debug("INFTL: INFTL_foldchain(inftl=%p,thisVUC=%d,pending=%d)\n",
inftl, thisVUC, pendingblock);
memset(BlockMap, 0xff, sizeof(BlockMap));
memset(BlockDeleted, 0, sizeof(BlockDeleted));
@ -323,8 +321,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
* Chain, and the Erase Unit into which we are supposed to be copying.
* Go for it.
*/
DEBUG(MTD_DEBUG_LEVEL1, "INFTL: folding chain %d into unit %d\n",
thisVUC, targetEUN);
pr_debug("INFTL: folding chain %d into unit %d\n", thisVUC, targetEUN);
for (block = 0; block < inftl->EraseSize/SECTORSIZE ; block++) {
unsigned char movebuf[SECTORSIZE];
@ -349,14 +346,13 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
ret = mtd->read(mtd, (inftl->EraseSize * BlockMap[block]) +
(block * SECTORSIZE), SECTORSIZE, &retlen,
movebuf);
if (ret < 0 && ret != -EUCLEAN) {
if (ret < 0 && !mtd_is_bitflip(ret)) {
ret = mtd->read(mtd,
(inftl->EraseSize * BlockMap[block]) +
(block * SECTORSIZE), SECTORSIZE,
&retlen, movebuf);
if (ret != -EIO)
DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
"away on retry?\n");
pr_debug("INFTL: error went away on retry?\n");
}
memset(&oob, 0xff, sizeof(struct inftl_oob));
oob.b.Status = oob.b.Status1 = SECTOR_USED;
@ -372,8 +368,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
* is important, by doing oldest first if we crash/reboot then it
* it is relatively simple to clean up the mess).
*/
DEBUG(MTD_DEBUG_LEVEL1, "INFTL: want to erase virtual chain %d\n",
thisVUC);
pr_debug("INFTL: want to erase virtual chain %d\n", thisVUC);
for (;;) {
/* Find oldest unit in chain. */
@ -421,7 +416,7 @@ static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
u16 ChainLength = 0, thislen;
u16 chain, EUN;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_makefreeblock(inftl=%p,"
pr_debug("INFTL: INFTL_makefreeblock(inftl=%p,"
"pending=%d)\n", inftl, pendingblock);
for (chain = 0; chain < inftl->nb_blocks; chain++) {
@ -484,8 +479,8 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
size_t retlen;
int silly, silly2 = 3;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findwriteunit(inftl=%p,"
"block=%d)\n", inftl, block);
pr_debug("INFTL: INFTL_findwriteunit(inftl=%p,block=%d)\n",
inftl, block);
do {
/*
@ -501,8 +496,8 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
blockofs, 8, &retlen, (char *)&bci);
status = bci.Status | bci.Status1;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in "
"EUN %d is %x\n", block , writeEUN, status);
pr_debug("INFTL: status of block %d in EUN %d is %x\n",
block , writeEUN, status);
switch(status) {
case SECTOR_FREE:
@ -555,9 +550,9 @@ hitused:
* Hopefully we free something, lets try again.
* This time we are desperate...
*/
DEBUG(MTD_DEBUG_LEVEL1, "INFTL: using desperate==1 "
"to find free EUN to accommodate write to "
"VUC %d\n", thisVUC);
pr_debug("INFTL: using desperate==1 to find free EUN "
"to accommodate write to VUC %d\n",
thisVUC);
writeEUN = INFTL_findfreeblock(inftl, 1);
if (writeEUN == BLOCK_NIL) {
/*
@ -647,7 +642,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
struct inftl_bci bci;
size_t retlen;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_trydeletechain(inftl=%p,"
pr_debug("INFTL: INFTL_trydeletechain(inftl=%p,"
"thisVUC=%d)\n", inftl, thisVUC);
memset(BlockUsed, 0, sizeof(BlockUsed));
@ -711,7 +706,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
* For each block in the chain free it and make it available
* for future use. Erase from the oldest unit first.
*/
DEBUG(MTD_DEBUG_LEVEL1, "INFTL: deleting empty VUC %d\n", thisVUC);
pr_debug("INFTL: deleting empty VUC %d\n", thisVUC);
for (;;) {
u16 *prevEUN = &inftl->VUtable[thisVUC];
@ -719,7 +714,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
/* If the chain is all gone already, we're done */
if (thisEUN == BLOCK_NIL) {
DEBUG(MTD_DEBUG_LEVEL2, "INFTL: Empty VUC %d for deletion was already absent\n", thisEUN);
pr_debug("INFTL: Empty VUC %d for deletion was already absent\n", thisEUN);
return;
}
@ -731,7 +726,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
thisEUN = *prevEUN;
}
DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n",
pr_debug("Deleting EUN %d from VUC %d\n",
thisEUN, thisVUC);
if (INFTL_formatblock(inftl, thisEUN) < 0) {
@ -767,7 +762,7 @@ static int INFTL_deleteblock(struct INFTLrecord *inftl, unsigned block)
size_t retlen;
struct inftl_bci bci;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_deleteblock(inftl=%p,"
pr_debug("INFTL: INFTL_deleteblock(inftl=%p,"
"block=%d)\n", inftl, block);
while (thisEUN < inftl->nb_blocks) {
@ -826,7 +821,7 @@ static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
struct inftl_oob oob;
char *p, *pend;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_writeblock(inftl=%p,block=%ld,"
pr_debug("INFTL: inftl_writeblock(inftl=%p,block=%ld,"
"buffer=%p)\n", inftl, block, buffer);
/* Is block all zero? */
@ -876,7 +871,7 @@ static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
struct inftl_bci bci;
size_t retlen;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=%p,block=%ld,"
pr_debug("INFTL: inftl_readblock(inftl=%p,block=%ld,"
"buffer=%p)\n", inftl, block, buffer);
while (thisEUN < inftl->nb_blocks) {
@ -922,7 +917,7 @@ foundit:
int ret = mtd->read(mtd, ptr, SECTORSIZE, &retlen, buffer);
/* Handle corrected bit flips gracefully */
if (ret < 0 && ret != -EUCLEAN)
if (ret < 0 && !mtd_is_bitflip(ret))
return -EIO;
}
return 0;

View File

@ -53,7 +53,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
struct INFTLPartition *ip;
size_t retlen;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: find_boot_record(inftl=%p)\n", inftl);
pr_debug("INFTL: find_boot_record(inftl=%p)\n", inftl);
/*
* Assume logical EraseSize == physical erasesize for starting the
@ -139,24 +139,20 @@ static int find_boot_record(struct INFTLrecord *inftl)
mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
#ifdef CONFIG_MTD_DEBUG_VERBOSE
if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
printk("INFTL: Media Header ->\n"
" bootRecordID = %s\n"
" NoOfBootImageBlocks = %d\n"
" NoOfBinaryPartitions = %d\n"
" NoOfBDTLPartitions = %d\n"
" BlockMultiplerBits = %d\n"
" FormatFlgs = %d\n"
" OsakVersion = 0x%x\n"
" PercentUsed = %d\n",
mh->bootRecordID, mh->NoOfBootImageBlocks,
mh->NoOfBinaryPartitions,
mh->NoOfBDTLPartitions,
mh->BlockMultiplierBits, mh->FormatFlags,
mh->OsakVersion, mh->PercentUsed);
}
#endif
pr_debug("INFTL: Media Header ->\n"
" bootRecordID = %s\n"
" NoOfBootImageBlocks = %d\n"
" NoOfBinaryPartitions = %d\n"
" NoOfBDTLPartitions = %d\n"
" BlockMultiplerBits = %d\n"
" FormatFlgs = %d\n"
" OsakVersion = 0x%x\n"
" PercentUsed = %d\n",
mh->bootRecordID, mh->NoOfBootImageBlocks,
mh->NoOfBinaryPartitions,
mh->NoOfBDTLPartitions,
mh->BlockMultiplierBits, mh->FormatFlags,
mh->OsakVersion, mh->PercentUsed);
if (mh->NoOfBDTLPartitions == 0) {
printk(KERN_WARNING "INFTL: Media Header sanity check "
@ -200,19 +196,15 @@ static int find_boot_record(struct INFTLrecord *inftl)
ip->spareUnits = le32_to_cpu(ip->spareUnits);
ip->Reserved0 = le32_to_cpu(ip->Reserved0);
#ifdef CONFIG_MTD_DEBUG_VERBOSE
if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
printk(" PARTITION[%d] ->\n"
" virtualUnits = %d\n"
" firstUnit = %d\n"
" lastUnit = %d\n"
" flags = 0x%x\n"
" spareUnits = %d\n",
i, ip->virtualUnits, ip->firstUnit,
ip->lastUnit, ip->flags,
ip->spareUnits);
}
#endif
pr_debug(" PARTITION[%d] ->\n"
" virtualUnits = %d\n"
" firstUnit = %d\n"
" lastUnit = %d\n"
" flags = 0x%x\n"
" spareUnits = %d\n",
i, ip->virtualUnits, ip->firstUnit,
ip->lastUnit, ip->flags,
ip->spareUnits);
if (ip->Reserved0 != ip->firstUnit) {
struct erase_info *instr = &inftl->instr;
@ -375,7 +367,7 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
*
* Return: 0 when succeed, -1 on error.
*
* ToDo: 1. Is it neceressary to check_free_sector after erasing ??
* ToDo: 1. Is it necessary to check_free_sector after erasing ??
*/
int INFTL_formatblock(struct INFTLrecord *inftl, int block)
{
@ -385,8 +377,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
struct mtd_info *mtd = inftl->mbd.mtd;
int physblock;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=%p,"
"block=%d)\n", inftl, block);
pr_debug("INFTL: INFTL_formatblock(inftl=%p,block=%d)\n", inftl, block);
memset(instr, 0, sizeof(struct erase_info));
@ -476,30 +467,30 @@ void INFTL_dumptables(struct INFTLrecord *s)
{
int i;
printk("-------------------------------------------"
pr_debug("-------------------------------------------"
"----------------------------------\n");
printk("VUtable[%d] ->", s->nb_blocks);
pr_debug("VUtable[%d] ->", s->nb_blocks);
for (i = 0; i < s->nb_blocks; i++) {
if ((i % 8) == 0)
printk("\n%04x: ", i);
printk("%04x ", s->VUtable[i]);
pr_debug("\n%04x: ", i);
pr_debug("%04x ", s->VUtable[i]);
}
printk("\n-------------------------------------------"
pr_debug("\n-------------------------------------------"
"----------------------------------\n");
printk("PUtable[%d-%d=%d] ->", s->firstEUN, s->lastEUN, s->nb_blocks);
pr_debug("PUtable[%d-%d=%d] ->", s->firstEUN, s->lastEUN, s->nb_blocks);
for (i = 0; i <= s->lastEUN; i++) {
if ((i % 8) == 0)
printk("\n%04x: ", i);
printk("%04x ", s->PUtable[i]);
pr_debug("\n%04x: ", i);
pr_debug("%04x ", s->PUtable[i]);
}
printk("\n-------------------------------------------"
pr_debug("\n-------------------------------------------"
"----------------------------------\n");
printk("INFTL ->\n"
pr_debug("INFTL ->\n"
" EraseSize = %d\n"
" h/s/c = %d/%d/%d\n"
" numvunits = %d\n"
@ -513,7 +504,7 @@ void INFTL_dumptables(struct INFTLrecord *s)
s->numvunits, s->firstEUN, s->lastEUN, s->numfreeEUNs,
s->LastFreeEUN, s->nb_blocks, s->nb_boot_blocks);
printk("\n-------------------------------------------"
pr_debug("\n-------------------------------------------"
"----------------------------------\n");
}
@ -521,25 +512,25 @@ void INFTL_dumpVUchains(struct INFTLrecord *s)
{
int logical, block, i;
printk("-------------------------------------------"
pr_debug("-------------------------------------------"
"----------------------------------\n");
printk("INFTL Virtual Unit Chains:\n");
pr_debug("INFTL Virtual Unit Chains:\n");
for (logical = 0; logical < s->nb_blocks; logical++) {
block = s->VUtable[logical];
if (block > s->nb_blocks)
continue;
printk(" LOGICAL %d --> %d ", logical, block);
pr_debug(" LOGICAL %d --> %d ", logical, block);
for (i = 0; i < s->nb_blocks; i++) {
if (s->PUtable[block] == BLOCK_NIL)
break;
block = s->PUtable[block];
printk("%d ", block);
pr_debug("%d ", block);
}
printk("\n");
pr_debug("\n");
}
printk("-------------------------------------------"
pr_debug("-------------------------------------------"
"----------------------------------\n");
}
@ -555,7 +546,7 @@ int INFTL_mount(struct INFTLrecord *s)
int i;
u8 *ANACtable, ANAC;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_mount(inftl=%p)\n", s);
pr_debug("INFTL: INFTL_mount(inftl=%p)\n", s);
/* Search for INFTL MediaHeader and Spare INFTL Media Header */
if (find_boot_record(s) < 0) {
@ -585,7 +576,7 @@ int INFTL_mount(struct INFTLrecord *s)
* NOTEXPLORED state. Then at the end we will try to format it and
* mark it as free.
*/
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 1, explore each unit\n");
pr_debug("INFTL: pass 1, explore each unit\n");
for (first_block = s->firstEUN; first_block <= s->lastEUN; first_block++) {
if (s->PUtable[first_block] != BLOCK_NOTEXPLORED)
continue;
@ -717,17 +708,14 @@ int INFTL_mount(struct INFTLrecord *s)
logical_block = BLOCK_NIL;
}
#ifdef CONFIG_MTD_DEBUG_VERBOSE
if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
INFTL_dumptables(s);
#endif
INFTL_dumptables(s);
/*
* Second pass, check for infinite loops in chains. These are
* possible because we don't update the previous pointers when
* we fold chains. No big deal, just fix them up in PUtable.
*/
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 2, validate virtual chains\n");
pr_debug("INFTL: pass 2, validate virtual chains\n");
for (logical_block = 0; logical_block < s->numvunits; logical_block++) {
block = s->VUtable[logical_block];
last_block = BLOCK_NIL;
@ -772,12 +760,8 @@ int INFTL_mount(struct INFTLrecord *s)
}
}
#ifdef CONFIG_MTD_DEBUG_VERBOSE
if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
INFTL_dumptables(s);
if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
INFTL_dumpVUchains(s);
#endif
INFTL_dumptables(s);
INFTL_dumpVUchains(s);
/*
* Third pass, format unreferenced blocks and init free block count.
@ -785,7 +769,7 @@ int INFTL_mount(struct INFTLrecord *s)
s->numfreeEUNs = 0;
s->LastFreeEUN = BLOCK_NIL;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 3, format unused blocks\n");
pr_debug("INFTL: pass 3, format unused blocks\n");
for (block = s->firstEUN; block <= s->lastEUN; block++) {
if (s->PUtable[block] == BLOCK_NOTEXPLORED) {
printk("INFTL: unreferenced block %d, formatting it\n",

View File

@ -41,8 +41,6 @@ config MTD_PHYSMAP_START
are mapped on your particular target board. Refer to the
memory map which should hopefully be in the documentation for
your board.
Ignore this option if you use run-time physmap configuration
(i.e., run-time calling physmap_configure()).
config MTD_PHYSMAP_LEN
hex "Physical length of flash mapping"
@ -55,8 +53,6 @@ config MTD_PHYSMAP_LEN
than the total amount of flash present. Refer to the memory
map which should hopefully be in the documentation for your
board.
Ignore this option if you use run-time physmap configuration
(i.e., run-time calling physmap_configure()).
config MTD_PHYSMAP_BANKWIDTH
int "Bank width in octets"
@ -67,8 +63,6 @@ config MTD_PHYSMAP_BANKWIDTH
in octets. For example, if you have a data bus width of 32
bits, you would set the bus width octet value to 4. This is
used internally by the CFI drivers.
Ignore this option if you use run-time physmap configuration
(i.e., run-time calling physmap_configure()).
config MTD_PHYSMAP_OF
tristate "Flash device in physical memory map based on OF description"
@ -260,7 +254,6 @@ config MTD_BCM963XX
config MTD_LANTIQ
tristate "Lantiq SoC NOR support"
depends on LANTIQ
select MTD_PARTITIONS
help
Support for NOR flash attached to the Lantiq SoC's External Bus Unit.
@ -339,10 +332,6 @@ config MTD_SOLUTIONENGINE
This enables access to the flash chips on the Hitachi SolutionEngine and
similar boards. Say 'Y' if you are building a kernel for such a board.
config MTD_ARM_INTEGRATOR
tristate "CFI Flash device mapped on ARM Integrator/P720T"
depends on ARM && MTD_CFI
config MTD_CDB89712
tristate "Cirrus CDB89712 evaluation board mappings"
depends on MTD_CFI && ARCH_CDB89712
@ -398,13 +387,6 @@ config MTD_AUTCPU12
This enables access to the NV-RAM on autronix autcpu12 board.
If you have such a board, say 'Y'.
config MTD_EDB7312
tristate "CFI Flash device mapped on EDB7312"
depends on ARCH_EDB7312 && MTD_CFI
help
This enables access to the CFI Flash on the Cogent EDB7312 board.
If you have such a board, say 'Y' here.
config MTD_IMPA7
tristate "JEDEC Flash device mapped on impA7"
depends on ARM && MTD_JEDECPROBE
@ -412,14 +394,6 @@ config MTD_IMPA7
This enables access to the NOR Flash on the impA7 board of
implementa GmbH. If you have such a board, say 'Y' here.
config MTD_CEIVA
tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame"
depends on MTD_JEDECPROBE && ARCH_CEIVA
help
This enables access to the flash chips on the Ceiva/Polaroid
PhotoMax Digital Picture Frame.
If you have such a device, say 'Y'.
config MTD_H720X
tristate "Hynix evaluation board mappings"
depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )

View File

@ -19,7 +19,6 @@ obj-$(CONFIG_MTD_CK804XROM) += ck804xrom.o
obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
obj-$(CONFIG_MTD_PXA2XX) += pxa2xx-flash.o
obj-$(CONFIG_MTD_MBX860) += mbx860.o
obj-$(CONFIG_MTD_CEIVA) += ceiva.o
obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o
@ -40,7 +39,6 @@ obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o
obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
obj-$(CONFIG_MTD_PCI) += pci.o
obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
obj-$(CONFIG_MTD_EDB7312) += edb7312.o
obj-$(CONFIG_MTD_IMPA7) += impa7.o
obj-$(CONFIG_MTD_FORTUNET) += fortunet.o
obj-$(CONFIG_MTD_UCLINUX) += uclinux.o

View File

@ -41,7 +41,6 @@ struct async_state {
uint32_t flash_ambctl0, flash_ambctl1;
uint32_t save_ambctl0, save_ambctl1;
unsigned long irq_flags;
struct mtd_partition *parts;
};
static void switch_to_flash(struct async_state *state)
@ -165,18 +164,8 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)
return -ENXIO;
}
ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0);
if (ret > 0) {
pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n");
mtd_device_register(state->mtd, pdata->parts, ret);
state->parts = pdata->parts;
} else if (pdata->nr_parts) {
pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n");
mtd_device_register(state->mtd, pdata->parts, pdata->nr_parts);
} else {
pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n");
mtd_device_register(state->mtd, NULL, 0);
}
mtd_device_parse_register(state->mtd, part_probe_types, 0,
pdata->parts, pdata->nr_parts);
platform_set_drvdata(pdev, state);
@ -188,7 +177,6 @@ static int __devexit bfin_flash_remove(struct platform_device *pdev)
struct async_state *state = platform_get_drvdata(pdev);
gpio_free(state->enet_flash_pin);
mtd_device_unregister(state->mtd);
kfree(state->parts);
map_destroy(state->mtd);
kfree(state);
return 0;

View File

@ -1,341 +0,0 @@
/*
* Ceiva flash memory driver.
* Copyright (C) 2002 Rob Scott <rscott@mtrob.fdns.net>
*
* Note: this driver supports jedec compatible devices. Modification
* for CFI compatible devices should be straight forward: change
* jedec_probe to cfi_probe.
*
* Based on: sa1100-flash.c, which has the following copyright:
* Flash memory access on SA11x0 based devices
*
* (C) 2000 Nicolas Pitre <nico@fluxnic.net>
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/concat.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/sizes.h>
/*
* This isn't complete yet, so...
*/
#define CONFIG_MTD_CEIVA_STATICMAP
#ifdef CONFIG_MTD_CEIVA_STATICMAP
/*
* See include/linux/mtd/partitions.h for definition of the mtd_partition
* structure.
*
* Please note:
* 1. The flash size given should be the largest flash size that can
* be accommodated.
*
* 2. The bus width must defined in clps_setup_flash.
*
* The MTD layer will detect flash chip aliasing and reduce the size of
* the map accordingly.
*
*/
#ifdef CONFIG_ARCH_CEIVA
/* Flash / Partition sizing */
/* For the 28F8003, we use the block mapping to calcuate the sizes */
#define MAX_SIZE_KiB (16 + 8 + 8 + 96 + (7*128))
#define BOOT_PARTITION_SIZE_KiB (16)
#define PARAMS_PARTITION_SIZE_KiB (8)
#define KERNEL_PARTITION_SIZE_KiB (4*128)
/* Use both remaining portion of first flash, and all of second flash */
#define ROOT_PARTITION_SIZE_KiB (3*128) + (8*128)
static struct mtd_partition ceiva_partitions[] = {
{
.name = "Ceiva BOOT partition",
.size = BOOT_PARTITION_SIZE_KiB*1024,
.offset = 0,
},{
.name = "Ceiva parameters partition",
.size = PARAMS_PARTITION_SIZE_KiB*1024,
.offset = (16 + 8) * 1024,
},{
.name = "Ceiva kernel partition",
.size = (KERNEL_PARTITION_SIZE_KiB)*1024,
.offset = 0x20000,
},{
.name = "Ceiva root filesystem partition",
.offset = MTDPART_OFS_APPEND,
.size = (ROOT_PARTITION_SIZE_KiB)*1024,
}
};
#endif
static int __init clps_static_partitions(struct mtd_partition **parts)
{
int nb_parts = 0;
#ifdef CONFIG_ARCH_CEIVA
if (machine_is_ceiva()) {
*parts = ceiva_partitions;
nb_parts = ARRAY_SIZE(ceiva_partitions);
}
#endif
return nb_parts;
}
#endif
struct clps_info {
unsigned long base;
unsigned long size;
int width;
void *vbase;
struct map_info *map;
struct mtd_info *mtd;
struct resource *res;
};
#define NR_SUBMTD 4
static struct clps_info info[NR_SUBMTD];
static int __init clps_setup_mtd(struct clps_info *clps, int nr, struct mtd_info **rmtd)
{
struct mtd_info *subdev[nr];
struct map_info *maps;
int i, found = 0, ret = 0;
/*
* Allocate the map_info structs in one go.
*/
maps = kzalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
if (!maps)
return -ENOMEM;
/*
* Claim and then map the memory regions.
*/
for (i = 0; i < nr; i++) {
if (clps[i].base == (unsigned long)-1)
break;
clps[i].res = request_mem_region(clps[i].base, clps[i].size, "clps flash");
if (!clps[i].res) {
ret = -EBUSY;
break;
}
clps[i].map = maps + i;
clps[i].map->name = "clps flash";
clps[i].map->phys = clps[i].base;
clps[i].vbase = ioremap(clps[i].base, clps[i].size);
if (!clps[i].vbase) {
ret = -ENOMEM;
break;
}
clps[i].map->virt = (void __iomem *)clps[i].vbase;
clps[i].map->bankwidth = clps[i].width;
clps[i].map->size = clps[i].size;
simple_map_init(&clps[i].map);
clps[i].mtd = do_map_probe("jedec_probe", clps[i].map);
if (clps[i].mtd == NULL) {
ret = -ENXIO;
break;
}
clps[i].mtd->owner = THIS_MODULE;
subdev[i] = clps[i].mtd;
printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, "
"%d-bit\n", clps[i].base, clps[i].mtd->size >> 20,
clps[i].width * 8);
found += 1;
}
/*
* ENXIO is special. It means we didn't find a chip when
* we probed. We need to tear down the mapping, free the
* resource and mark it as such.
*/
if (ret == -ENXIO) {
iounmap(clps[i].vbase);
clps[i].vbase = NULL;
release_resource(clps[i].res);
clps[i].res = NULL;
}
/*
* If we found one device, don't bother with concat support.
* If we found multiple devices, use concat if we have it
* available, otherwise fail.
*/
if (ret == 0 || ret == -ENXIO) {
if (found == 1) {
*rmtd = subdev[0];
ret = 0;
} else if (found > 1) {
/*
* We detected multiple devices. Concatenate
* them together.
*/
*rmtd = mtd_concat_create(subdev, found,
"clps flash");
if (*rmtd == NULL)
ret = -ENXIO;
}
}
/*
* If we failed, clean up.
*/
if (ret) {
do {
if (clps[i].mtd)
map_destroy(clps[i].mtd);
if (clps[i].vbase)
iounmap(clps[i].vbase);
if (clps[i].res)
release_resource(clps[i].res);
} while (i--);
kfree(maps);
}
return ret;
}
static void __exit clps_destroy_mtd(struct clps_info *clps, struct mtd_info *mtd)
{
int i;
mtd_device_unregister(mtd);
if (mtd != clps[0].mtd)
mtd_concat_destroy(mtd);
for (i = NR_SUBMTD; i >= 0; i--) {
if (clps[i].mtd)
map_destroy(clps[i].mtd);
if (clps[i].vbase)
iounmap(clps[i].vbase);
if (clps[i].res)
release_resource(clps[i].res);
}
kfree(clps[0].map);
}
/*
* We define the memory space, size, and width for the flash memory
* space here.
*/
static int __init clps_setup_flash(void)
{
int nr = 0;
#ifdef CONFIG_ARCH_CEIVA
if (machine_is_ceiva()) {
info[0].base = CS0_PHYS_BASE;
info[0].size = SZ_32M;
info[0].width = CEIVA_FLASH_WIDTH;
info[1].base = CS1_PHYS_BASE;
info[1].size = SZ_32M;
info[1].width = CEIVA_FLASH_WIDTH;
nr = 2;
}
#endif
return nr;
}
static struct mtd_partition *parsed_parts;
static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };
static void __init clps_locate_partitions(struct mtd_info *mtd)
{
const char *part_type = NULL;
int nr_parts = 0;
do {
/*
* Partition selection stuff.
*/
nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0);
if (nr_parts > 0) {
part_type = "command line";
break;
}
#ifdef CONFIG_MTD_CEIVA_STATICMAP
nr_parts = clps_static_partitions(&parsed_parts);
if (nr_parts > 0) {
part_type = "static";
break;
}
printk("found: %d partitions\n", nr_parts);
#endif
} while (0);
if (nr_parts == 0) {
printk(KERN_NOTICE "clps flash: no partition info "
"available, registering whole flash\n");
mtd_device_register(mtd, NULL, 0);
} else {
printk(KERN_NOTICE "clps flash: using %s partition "
"definition\n", part_type);
mtd_device_register(mtd, parsed_parts, nr_parts);
}
/* Always succeeds. */
}
static void __exit clps_destroy_partitions(void)
{
kfree(parsed_parts);
}
static struct mtd_info *mymtd;
static int __init clps_mtd_init(void)
{
int ret;
int nr;
nr = clps_setup_flash();
if (nr < 0)
return nr;
ret = clps_setup_mtd(info, nr, &mymtd);
if (ret)
return ret;
clps_locate_partitions(mymtd);
return 0;
}
static void __exit clps_mtd_cleanup(void)
{
clps_destroy_mtd(info, mymtd);
clps_destroy_partitions();
}
module_init(clps_mtd_init);
module_exit(clps_mtd_cleanup);
MODULE_AUTHOR("Rob Scott");
MODULE_DESCRIPTION("Cirrus Logic JEDEC map driver");
MODULE_LICENSE("GPL");

View File

@ -145,14 +145,10 @@ static struct map_info dc21285_map = {
/* Partition stuff */
static struct mtd_partition *dc21285_parts;
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
static int __init init_dc21285(void)
{
int nrparts;
/* Determine bankwidth */
switch (*CSR_SA110_CNTL & (3<<14)) {
case SA110_CNTL_ROMWIDTH_8:
@ -200,8 +196,7 @@ static int __init init_dc21285(void)
dc21285_mtd->owner = THIS_MODULE;
nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
mtd_device_register(dc21285_mtd, dc21285_parts, nrparts);
mtd_device_parse_register(dc21285_mtd, probes, 0, NULL, 0);
if(machine_is_ebsa285()) {
/*
@ -224,8 +219,6 @@ static int __init init_dc21285(void)
static void __exit cleanup_dc21285(void)
{
mtd_device_unregister(dc21285_mtd);
if (dc21285_parts)
kfree(dc21285_parts);
map_destroy(dc21285_mtd);
iounmap(dc21285_map.virt);
}

View File

@ -1,134 +0,0 @@
/*
* Handle mapping of the NOR flash on Cogent EDB7312 boards
*
* Copyright 2002 SYSGO Real-Time Solutions GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#define WINDOW_ADDR 0x00000000 /* physical properties of flash */
#define WINDOW_SIZE 0x01000000
#define BUSWIDTH 2
#define FLASH_BLOCKSIZE_MAIN 0x20000
#define FLASH_NUMBLOCKS_MAIN 128
/* can be "cfi_probe", "jedec_probe", "map_rom", NULL }; */
#define PROBETYPES { "cfi_probe", NULL }
#define MSG_PREFIX "EDB7312-NOR:" /* prefix for our printk()'s */
#define MTDID "edb7312-nor" /* for mtdparts= partitioning */
static struct mtd_info *mymtd;
struct map_info edb7312nor_map = {
.name = "NOR flash on EDB7312",
.size = WINDOW_SIZE,
.bankwidth = BUSWIDTH,
.phys = WINDOW_ADDR,
};
/*
* MTD partitioning stuff
*/
static struct mtd_partition static_partitions[3] =
{
{
.name = "ARMboot",
.size = 0x40000,
.offset = 0
},
{
.name = "Kernel",
.size = 0x200000,
.offset = 0x40000
},
{
.name = "RootFS",
.size = 0xDC0000,
.offset = 0x240000
},
};
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
static int mtd_parts_nb = 0;
static struct mtd_partition *mtd_parts = 0;
static int __init init_edb7312nor(void)
{
static const char *rom_probe_types[] = PROBETYPES;
const char **type;
const char *part_type = 0;
printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
WINDOW_SIZE, WINDOW_ADDR);
edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
if (!edb7312nor_map.virt) {
printk(MSG_PREFIX "failed to ioremap\n");
return -EIO;
}
simple_map_init(&edb7312nor_map);
mymtd = 0;
type = rom_probe_types;
for(; !mymtd && *type; type++) {
mymtd = do_map_probe(*type, &edb7312nor_map);
}
if (mymtd) {
mymtd->owner = THIS_MODULE;
mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID);
if (mtd_parts_nb > 0)
part_type = "detected";
if (mtd_parts_nb == 0) {
mtd_parts = static_partitions;
mtd_parts_nb = ARRAY_SIZE(static_partitions);
part_type = "static";
}
if (mtd_parts_nb == 0)
printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
else
printk(KERN_NOTICE MSG_PREFIX
"using %s partition definition\n", part_type);
/* Register the whole device first. */
mtd_device_register(mymtd, NULL, 0);
mtd_device_register(mymtd, mtd_parts, mtd_parts_nb);
return 0;
}
iounmap((void *)edb7312nor_map.virt);
return -ENXIO;
}
static void __exit cleanup_edb7312nor(void)
{
if (mymtd) {
mtd_device_unregister(mymtd);
map_destroy(mymtd);
}
if (edb7312nor_map.virt) {
iounmap((void *)edb7312nor_map.virt);
edb7312nor_map.virt = 0;
}
}
module_init(init_edb7312nor);
module_exit(cleanup_edb7312nor);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
MODULE_DESCRIPTION("Generic configurable MTD map driver");

View File

@ -187,7 +187,6 @@ static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
*/
static int __devinit gpio_flash_probe(struct platform_device *pdev)
{
int nr_parts;
size_t i, arr_size;
struct physmap_flash_data *pdata;
struct resource *memory;
@ -252,20 +251,9 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev)
return -ENXIO;
}
nr_parts = parse_mtd_partitions(state->mtd, part_probe_types,
&pdata->parts, 0);
if (nr_parts > 0) {
pr_devinit(KERN_NOTICE PFX "Using commandline partition definition\n");
kfree(pdata->parts);
} else if (pdata->nr_parts) {
pr_devinit(KERN_NOTICE PFX "Using board partition definition\n");
nr_parts = pdata->nr_parts;
} else {
pr_devinit(KERN_NOTICE PFX "no partition info available, registering whole flash at once\n");
nr_parts = 0;
}
mtd_device_register(state->mtd, pdata->parts, nr_parts);
mtd_device_parse_register(state->mtd, part_probe_types, 0,
pdata->parts, pdata->nr_parts);
return 0;
}

View File

@ -58,18 +58,11 @@ static struct mtd_partition h720x_partitions[] = {
#define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions)
static int nr_mtd_parts;
static struct mtd_partition *mtd_parts;
static const char *probes[] = { "cmdlinepart", NULL };
/*
* Initialize FLASH support
*/
static int __init h720x_mtd_init(void)
{
char *part_type = NULL;
h720x_map.virt = ioremap(h720x_map.phys, h720x_map.size);
if (!h720x_map.virt) {
@ -92,16 +85,8 @@ static int __init h720x_mtd_init(void)
if (mymtd) {
mymtd->owner = THIS_MODULE;
nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0);
if (nr_mtd_parts > 0)
part_type = "command line";
if (nr_mtd_parts <= 0) {
mtd_parts = h720x_partitions;
nr_mtd_parts = NUM_PARTITIONS;
part_type = "builtin";
}
printk(KERN_INFO "Using %s partition table\n", part_type);
mtd_device_register(mymtd, mtd_parts, nr_mtd_parts);
mtd_device_parse_register(mymtd, NULL, 0,
h720x_partitions, NUM_PARTITIONS);
return 0;
}
@ -120,10 +105,6 @@ static void __exit h720x_mtd_cleanup(void)
map_destroy(mymtd);
}
/* Free partition info, if commandline partition was used */
if (mtd_parts && (mtd_parts != h720x_partitions))
kfree (mtd_parts);
if (h720x_map.virt) {
iounmap((void *)h720x_map.virt);
h720x_map.virt = 0;

View File

@ -49,7 +49,7 @@ static struct map_info impa7_map[NUM_FLASHBANKS] = {
/*
* MTD partitioning stuff
*/
static struct mtd_partition static_partitions[] =
static struct mtd_partition partitions[] =
{
{
.name = "FileSystem",
@ -58,16 +58,10 @@ static struct mtd_partition static_partitions[] =
},
};
static int mtd_parts_nb[NUM_FLASHBANKS];
static struct mtd_partition *mtd_parts[NUM_FLASHBANKS];
static const char *probes[] = { "cmdlinepart", NULL };
static int __init init_impa7(void)
{
static const char *rom_probe_types[] = PROBETYPES;
const char **type;
const char *part_type = 0;
int i;
static struct { u_long addr; u_long size; } pt[NUM_FLASHBANKS] = {
{ WINDOW_ADDR0, WINDOW_SIZE0 },
@ -97,23 +91,9 @@ static int __init init_impa7(void)
if (impa7_mtd[i]) {
impa7_mtd[i]->owner = THIS_MODULE;
devicesfound++;
mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
probes,
&mtd_parts[i],
0);
if (mtd_parts_nb[i] > 0) {
part_type = "command line";
} else {
mtd_parts[i] = static_partitions;
mtd_parts_nb[i] = ARRAY_SIZE(static_partitions);
part_type = "static";
}
printk(KERN_NOTICE MSG_PREFIX
"using %s partition definition\n",
part_type);
mtd_device_register(impa7_mtd[i],
mtd_parts[i], mtd_parts_nb[i]);
mtd_device_parse_register(impa7_mtd[i], NULL, 0,
partitions,
ARRAY_SIZE(partitions));
}
else
iounmap((void *)impa7_map[i].virt);

View File

@ -44,7 +44,6 @@ struct vr_nor_mtd {
void __iomem *csr_base;
struct map_info map;
struct mtd_info *info;
int nr_parts;
struct pci_dev *dev;
};
@ -71,13 +70,9 @@ static void __devexit vr_nor_destroy_partitions(struct vr_nor_mtd *p)
static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p)
{
struct mtd_partition *parts;
static const char *part_probes[] = { "cmdlinepart", NULL };
/* register the flash bank */
/* partition the flash bank */
p->nr_parts = parse_mtd_partitions(p->info, part_probes, &parts, 0);
return mtd_device_register(p->info, parts, p->nr_parts);
return mtd_device_parse_register(p->info, NULL, 0, NULL, 0);
}
static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p)

View File

@ -38,7 +38,6 @@
struct ixp2000_flash_info {
struct mtd_info *mtd;
struct map_info map;
struct mtd_partition *partitions;
struct resource *res;
};
@ -125,8 +124,6 @@ static int ixp2000_flash_remove(struct platform_device *dev)
if (info->map.map_priv_1)
iounmap((void *) info->map.map_priv_1);
kfree(info->partitions);
if (info->res) {
release_resource(info->res);
kfree(info->res);
@ -229,13 +226,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
}
info->mtd->owner = THIS_MODULE;
err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
if (err > 0) {
err = mtd_device_register(info->mtd, info->partitions, err);
if(err)
dev_err(&dev->dev, "Could not parse partitions\n");
}
err = mtd_device_parse_register(info->mtd, probes, 0, NULL, 0);
if (err)
goto Error;

View File

@ -145,7 +145,6 @@ static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
struct ixp4xx_flash_info {
struct mtd_info *mtd;
struct map_info map;
struct mtd_partition *partitions;
struct resource *res;
};
@ -168,8 +167,6 @@ static int ixp4xx_flash_remove(struct platform_device *dev)
if (info->map.virt)
iounmap(info->map.virt);
kfree(info->partitions);
if (info->res) {
release_resource(info->res);
kfree(info->res);
@ -185,8 +182,6 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
{
struct flash_platform_data *plat = dev->dev.platform_data;
struct ixp4xx_flash_info *info;
const char *part_type = NULL;
int nr_parts = 0;
int err = -1;
if (!plat)
@ -252,28 +247,12 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
/* Use the fast version */
info->map.write = ixp4xx_write16;
nr_parts = parse_mtd_partitions(info->mtd, probes, &info->partitions,
dev->resource->start);
if (nr_parts > 0) {
part_type = "dynamic";
} else {
info->partitions = plat->parts;
nr_parts = plat->nr_parts;
part_type = "static";
}
if (nr_parts == 0)
printk(KERN_NOTICE "IXP4xx flash: no partition info "
"available, registering whole flash\n");
else
printk(KERN_NOTICE "IXP4xx flash: using %s partition "
"definition\n", part_type);
err = mtd_device_register(info->mtd, info->partitions, nr_parts);
if (err)
err = mtd_device_parse_register(info->mtd, probes, dev->resource->start,
plat->parts, plat->nr_parts);
if (err) {
printk(KERN_ERR "Could not parse partitions\n");
if (err)
goto Error;
}
return 0;

View File

@ -107,16 +107,12 @@ ltq_copy_to(struct map_info *map, unsigned long to,
spin_unlock_irqrestore(&ebu_lock, flags);
}
static const char const *part_probe_types[] = { "cmdlinepart", NULL };
static int __init
ltq_mtd_probe(struct platform_device *pdev)
{
struct physmap_flash_data *ltq_mtd_data = dev_get_platdata(&pdev->dev);
struct ltq_mtd *ltq_mtd;
struct mtd_partition *parts;
struct resource *res;
int nr_parts = 0;
struct cfi_private *cfi;
int err;
@ -172,17 +168,8 @@ ltq_mtd_probe(struct platform_device *pdev)
cfi->addr_unlock1 ^= 1;
cfi->addr_unlock2 ^= 1;
nr_parts = parse_mtd_partitions(ltq_mtd->mtd,
part_probe_types, &parts, 0);
if (nr_parts > 0) {
dev_info(&pdev->dev,
"using %d partitions from cmdline", nr_parts);
} else {
nr_parts = ltq_mtd_data->nr_parts;
parts = ltq_mtd_data->parts;
}
err = mtd_device_register(ltq_mtd->mtd, parts, nr_parts);
err = mtd_device_parse_register(ltq_mtd->mtd, NULL, 0,
ltq_mtd_data->parts, ltq_mtd_data->nr_parts);
if (err) {
dev_err(&pdev->dev, "failed to add partitions\n");
goto err_destroy;

View File

@ -33,9 +33,6 @@ struct latch_addr_flash_info {
/* cache; could be found out of res */
unsigned long win_mask;
int nr_parts;
struct mtd_partition *parts;
spinlock_t lock;
};
@ -97,8 +94,6 @@ static void lf_copy_from(struct map_info *map, void *to,
static char *rom_probe_types[] = { "cfi_probe", NULL };
static char *part_probe_types[] = { "cmdlinepart", NULL };
static int latch_addr_flash_remove(struct platform_device *dev)
{
struct latch_addr_flash_info *info;
@ -112,8 +107,6 @@ static int latch_addr_flash_remove(struct platform_device *dev)
latch_addr_data = dev->dev.platform_data;
if (info->mtd != NULL) {
if (info->nr_parts)
kfree(info->parts);
mtd_device_unregister(info->mtd);
map_destroy(info->mtd);
}
@ -206,21 +199,8 @@ static int __devinit latch_addr_flash_probe(struct platform_device *dev)
}
info->mtd->owner = THIS_MODULE;
err = parse_mtd_partitions(info->mtd, (const char **)part_probe_types,
&info->parts, 0);
if (err > 0) {
mtd_device_register(info->mtd, info->parts, err);
return 0;
}
if (latch_addr_data->nr_parts) {
pr_notice("Using latch-addr-flash partition information\n");
mtd_device_register(info->mtd,
latch_addr_data->parts,
latch_addr_data->nr_parts);
return 0;
}
mtd_device_register(info->mtd, NULL, 0);
mtd_device_parse_register(info->mtd, NULL, 0,
latch_addr_data->parts, latch_addr_data->nr_parts);
return 0;
iounmap:

View File

@ -22,22 +22,6 @@
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
#ifdef CONFIG_MTD_DEBUG
static int debug = CONFIG_MTD_DEBUG_VERBOSE;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy");
#undef DEBUG
#define DEBUG(n, format, arg...) \
if (n <= debug) { \
printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \
}
#else
#undef DEBUG
#define DEBUG(n, arg...)
static const int debug = 0;
#endif
#define info(format, arg...) printk(KERN_INFO "pcmciamtd: " format "\n" , ## arg)
#define DRIVER_DESC "PCMCIA Flash memory card driver"
@ -105,13 +89,13 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
int ret;
if (!pcmcia_dev_present(dev->p_dev)) {
DEBUG(1, "device removed");
pr_debug("device removed\n");
return 0;
}
offset = to & ~(dev->win_size-1);
if (offset != dev->offset) {
DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
pr_debug("Remapping window from 0x%8.8x to 0x%8.8x\n",
dev->offset, offset);
ret = pcmcia_map_mem_page(dev->p_dev, win, offset);
if (ret != 0)
@ -132,7 +116,7 @@ static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs)
return d;
d.x[0] = readb(addr);
DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02lx", ofs, addr, d.x[0]);
pr_debug("ofs = 0x%08lx (%p) data = 0x%02lx\n", ofs, addr, d.x[0]);
return d;
}
@ -147,7 +131,7 @@ static map_word pcmcia_read16_remap(struct map_info *map, unsigned long ofs)
return d;
d.x[0] = readw(addr);
DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04lx", ofs, addr, d.x[0]);
pr_debug("ofs = 0x%08lx (%p) data = 0x%04lx\n", ofs, addr, d.x[0]);
return d;
}
@ -157,7 +141,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
unsigned long win_size = dev->win_size;
DEBUG(3, "to = %p from = %lu len = %zd", to, from, len);
pr_debug("to = %p from = %lu len = %zd\n", to, from, len);
while(len) {
int toread = win_size - (from & (win_size-1));
caddr_t addr;
@ -169,7 +153,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
if(!addr)
return;
DEBUG(4, "memcpy from %p to %p len = %d", addr, to, toread);
pr_debug("memcpy from %p to %p len = %d\n", addr, to, toread);
memcpy_fromio(to, addr, toread);
len -= toread;
to += toread;
@ -185,7 +169,7 @@ static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long
if(!addr)
return;
DEBUG(3, "adr = 0x%08lx (%p) data = 0x%02lx", adr, addr, d.x[0]);
pr_debug("adr = 0x%08lx (%p) data = 0x%02lx\n", adr, addr, d.x[0]);
writeb(d.x[0], addr);
}
@ -196,7 +180,7 @@ static void pcmcia_write16_remap(struct map_info *map, map_word d, unsigned long
if(!addr)
return;
DEBUG(3, "adr = 0x%08lx (%p) data = 0x%04lx", adr, addr, d.x[0]);
pr_debug("adr = 0x%08lx (%p) data = 0x%04lx\n", adr, addr, d.x[0]);
writew(d.x[0], addr);
}
@ -206,7 +190,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
unsigned long win_size = dev->win_size;
DEBUG(3, "to = %lu from = %p len = %zd", to, from, len);
pr_debug("to = %lu from = %p len = %zd\n", to, from, len);
while(len) {
int towrite = win_size - (to & (win_size-1));
caddr_t addr;
@ -218,7 +202,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
if(!addr)
return;
DEBUG(4, "memcpy from %p to %p len = %d", from, addr, towrite);
pr_debug("memcpy from %p to %p len = %d\n", from, addr, towrite);
memcpy_toio(addr, from, towrite);
len -= towrite;
to += towrite;
@ -240,7 +224,7 @@ static map_word pcmcia_read8(struct map_info *map, unsigned long ofs)
return d;
d.x[0] = readb(win_base + ofs);
DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02lx",
pr_debug("ofs = 0x%08lx (%p) data = 0x%02lx\n",
ofs, win_base + ofs, d.x[0]);
return d;
}
@ -255,7 +239,7 @@ static map_word pcmcia_read16(struct map_info *map, unsigned long ofs)
return d;
d.x[0] = readw(win_base + ofs);
DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04lx",
pr_debug("ofs = 0x%08lx (%p) data = 0x%04lx\n",
ofs, win_base + ofs, d.x[0]);
return d;
}
@ -268,7 +252,7 @@ static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from,
if(DEV_REMOVED(map))
return;
DEBUG(3, "to = %p from = %lu len = %zd", to, from, len);
pr_debug("to = %p from = %lu len = %zd\n", to, from, len);
memcpy_fromio(to, win_base + from, len);
}
@ -280,7 +264,7 @@ static void pcmcia_write8(struct map_info *map, map_word d, unsigned long adr)
if(DEV_REMOVED(map))
return;
DEBUG(3, "adr = 0x%08lx (%p) data = 0x%02lx",
pr_debug("adr = 0x%08lx (%p) data = 0x%02lx\n",
adr, win_base + adr, d.x[0]);
writeb(d.x[0], win_base + adr);
}
@ -293,7 +277,7 @@ static void pcmcia_write16(struct map_info *map, map_word d, unsigned long adr)
if(DEV_REMOVED(map))
return;
DEBUG(3, "adr = 0x%08lx (%p) data = 0x%04lx",
pr_debug("adr = 0x%08lx (%p) data = 0x%04lx\n",
adr, win_base + adr, d.x[0]);
writew(d.x[0], win_base + adr);
}
@ -306,7 +290,7 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f
if(DEV_REMOVED(map))
return;
DEBUG(3, "to = %lu from = %p len = %zd", to, from, len);
pr_debug("to = %lu from = %p len = %zd\n", to, from, len);
memcpy_toio(win_base + to, from, len);
}
@ -316,7 +300,7 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
struct pcmcia_device *link = dev->p_dev;
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
pr_debug("dev = %p on = %d vpp = %d\n\n", dev, on, dev->vpp);
pcmcia_fixup_vpp(link, on ? dev->vpp : 0);
}
@ -325,7 +309,7 @@ static void pcmciamtd_release(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev = link->priv;
DEBUG(3, "link = 0x%p", link);
pr_debug("link = 0x%p\n", link);
if (link->resource[2]->end) {
if(dev->win_base) {
@ -337,7 +321,6 @@ static void pcmciamtd_release(struct pcmcia_device *link)
}
#ifdef CONFIG_MTD_DEBUG
static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
tuple_t *tuple,
void *priv_data)
@ -347,7 +330,7 @@ static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
if (!pcmcia_parse_tuple(tuple, &parse)) {
cistpl_format_t *t = &parse.format;
(void)t; /* Shut up, gcc */
DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
pr_debug("Format type: %u, Error Detection: %u, offset = %u, length =%u\n",
t->type, t->edc, t->offset, t->length);
}
return -ENOSPC;
@ -363,12 +346,11 @@ static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev,
if (!pcmcia_parse_tuple(tuple, &parse)) {
cistpl_jedec_t *t = &parse.jedec;
for (i = 0; i < t->nid; i++)
DEBUG(2, "JEDEC: 0x%02x 0x%02x",
pr_debug("JEDEC: 0x%02x 0x%02x\n",
t->id[i].mfr, t->id[i].info);
}
return -ENOSPC;
}
#endif
static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
tuple_t *tuple,
@ -382,14 +364,14 @@ static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
if (pcmcia_parse_tuple(tuple, &parse))
return -EINVAL;
DEBUG(2, "Common memory:");
pr_debug("Common memory:\n");
dev->pcmcia_map.size = t->dev[0].size;
/* from here on: DEBUG only */
for (i = 0; i < t->ndev; i++) {
DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
pr_debug("Region %d, type = %u\n", i, t->dev[i].type);
pr_debug("Region %d, wp = %u\n", i, t->dev[i].wp);
pr_debug("Region %d, speed = %u ns\n", i, t->dev[i].speed);
pr_debug("Region %d, size = %u bytes\n", i, t->dev[i].size);
}
return 0;
}
@ -409,12 +391,12 @@ static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev,
dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
/* from here on: DEBUG only */
for (i = 0; i < t->ngeo; i++) {
DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
pr_debug("region: %d bankwidth = %u\n", i, t->geo[i].buswidth);
pr_debug("region: %d erase_block = %u\n", i, t->geo[i].erase_block);
pr_debug("region: %d read_block = %u\n", i, t->geo[i].read_block);
pr_debug("region: %d write_block = %u\n", i, t->geo[i].write_block);
pr_debug("region: %d partition = %u\n", i, t->geo[i].partition);
pr_debug("region: %d interleave = %u\n", i, t->geo[i].interleave);
}
return 0;
}
@ -432,13 +414,11 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
if (p_dev->prod_id[i])
strcat(dev->mtd_name, p_dev->prod_id[i]);
}
DEBUG(2, "Found name: %s", dev->mtd_name);
pr_debug("Found name: %s\n", dev->mtd_name);
}
#ifdef CONFIG_MTD_DEBUG
pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL);
pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL);
#endif
pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev);
pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev);
@ -450,12 +430,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
if(force_size) {
dev->pcmcia_map.size = force_size << 20;
DEBUG(2, "size forced to %dM", force_size);
pr_debug("size forced to %dM\n", force_size);
}
if(bankwidth) {
dev->pcmcia_map.bankwidth = bankwidth;
DEBUG(2, "bankwidth forced to %d", bankwidth);
pr_debug("bankwidth forced to %d\n", bankwidth);
}
dev->pcmcia_map.name = dev->mtd_name;
@ -464,7 +444,7 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
*new_name = 1;
}
DEBUG(1, "Device: Size: %lu Width:%d Name: %s",
pr_debug("Device: Size: %lu Width:%d Name: %s\n",
dev->pcmcia_map.size,
dev->pcmcia_map.bankwidth << 3, dev->mtd_name);
}
@ -479,7 +459,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
static char *probes[] = { "jedec_probe", "cfi_probe" };
int new_name = 0;
DEBUG(3, "link=0x%p", link);
pr_debug("link=0x%p\n", link);
card_settings(dev, link, &new_name);
@ -512,11 +492,11 @@ static int pcmciamtd_config(struct pcmcia_device *link)
do {
int ret;
DEBUG(2, "requesting window with size = %luKiB memspeed = %d",
pr_debug("requesting window with size = %luKiB memspeed = %d\n",
(unsigned long) resource_size(link->resource[2]) >> 10,
mem_speed);
ret = pcmcia_request_window(link, link->resource[2], mem_speed);
DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
pr_debug("ret = %d dev->win_size = %d\n", ret, dev->win_size);
if(ret) {
j++;
link->resource[2]->start = 0;
@ -524,21 +504,21 @@ static int pcmciamtd_config(struct pcmcia_device *link)
force_size << 20 : MAX_PCMCIA_ADDR;
link->resource[2]->end >>= j;
} else {
DEBUG(2, "Got window of size %luKiB", (unsigned long)
pr_debug("Got window of size %luKiB\n", (unsigned long)
resource_size(link->resource[2]) >> 10);
dev->win_size = resource_size(link->resource[2]);
break;
}
} while (link->resource[2]->end >= 0x1000);
DEBUG(2, "dev->win_size = %d", dev->win_size);
pr_debug("dev->win_size = %d\n", dev->win_size);
if(!dev->win_size) {
dev_err(&dev->p_dev->dev, "Cannot allocate memory window\n");
pcmciamtd_release(link);
return -ENODEV;
}
DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
pr_debug("Allocated a window of %dKiB\n", dev->win_size >> 10);
/* Get write protect status */
dev->win_base = ioremap(link->resource[2]->start,
@ -549,7 +529,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
pcmciamtd_release(link);
return -ENODEV;
}
DEBUG(1, "mapped window dev = %p @ %pR, base = %p",
pr_debug("mapped window dev = %p @ %pR, base = %p\n",
dev, link->resource[2], dev->win_base);
dev->offset = 0;
@ -564,7 +544,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
}
link->config_index = 0;
DEBUG(2, "Setting Configuration");
pr_debug("Setting Configuration\n");
ret = pcmcia_enable_device(link);
if (ret != 0) {
if (dev->win_base) {
@ -580,17 +560,17 @@ static int pcmciamtd_config(struct pcmcia_device *link)
mtd = do_map_probe("map_rom", &dev->pcmcia_map);
} else {
for(i = 0; i < ARRAY_SIZE(probes); i++) {
DEBUG(1, "Trying %s", probes[i]);
pr_debug("Trying %s\n", probes[i]);
mtd = do_map_probe(probes[i], &dev->pcmcia_map);
if(mtd)
break;
DEBUG(1, "FAILED: %s", probes[i]);
pr_debug("FAILED: %s\n", probes[i]);
}
}
if(!mtd) {
DEBUG(1, "Can not find an MTD");
pr_debug("Can not find an MTD\n");
pcmciamtd_release(link);
return -ENODEV;
}
@ -617,7 +597,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
/* If the memory found is fits completely into the mapped PCMCIA window,
use the faster non-remapping read/write functions */
if(mtd->size <= dev->win_size) {
DEBUG(1, "Using non remapping memory functions");
pr_debug("Using non remapping memory functions\n");
dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base;
if (dev->pcmcia_map.bankwidth == 1) {
dev->pcmcia_map.read = pcmcia_read8;
@ -645,7 +625,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
static int pcmciamtd_suspend(struct pcmcia_device *dev)
{
DEBUG(2, "EVENT_PM_RESUME");
pr_debug("EVENT_PM_RESUME\n");
/* get_lock(link); */
@ -654,7 +634,7 @@ static int pcmciamtd_suspend(struct pcmcia_device *dev)
static int pcmciamtd_resume(struct pcmcia_device *dev)
{
DEBUG(2, "EVENT_PM_SUSPEND");
pr_debug("EVENT_PM_SUSPEND\n");
/* free_lock(link); */
@ -666,7 +646,7 @@ static void pcmciamtd_detach(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev = link->priv;
DEBUG(3, "link=0x%p", link);
pr_debug("link=0x%p\n", link);
if(dev->mtd_info) {
mtd_device_unregister(dev->mtd_info);
@ -686,7 +666,7 @@ static int pcmciamtd_probe(struct pcmcia_device *link)
/* Create new memory card device */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) return -ENOMEM;
DEBUG(1, "dev=0x%p", dev);
pr_debug("dev=0x%p\n", dev);
dev->p_dev = link;
link->priv = dev;
@ -755,7 +735,7 @@ static int __init init_pcmciamtd(void)
static void __exit exit_pcmciamtd(void)
{
DEBUG(1, DRIVER_DESC " unloading");
pr_debug(DRIVER_DESC " unloading");
pcmcia_unregister_driver(&pcmciamtd_driver);
}

View File

@ -27,8 +27,6 @@ struct physmap_flash_info {
struct mtd_info *mtd[MAX_RESOURCES];
struct mtd_info *cmtd;
struct map_info map[MAX_RESOURCES];
int nr_parts;
struct mtd_partition *parts;
};
static int physmap_flash_remove(struct platform_device *dev)
@ -46,8 +44,6 @@ static int physmap_flash_remove(struct platform_device *dev)
if (info->cmtd) {
mtd_device_unregister(info->cmtd);
if (info->nr_parts)
kfree(info->parts);
if (info->cmtd != info->mtd[0])
mtd_concat_destroy(info->cmtd);
}
@ -175,23 +171,8 @@ static int physmap_flash_probe(struct platform_device *dev)
if (err)
goto err_out;
err = parse_mtd_partitions(info->cmtd, part_probe_types,
&info->parts, 0);
if (err > 0) {
mtd_device_register(info->cmtd, info->parts, err);
info->nr_parts = err;
return 0;
}
if (physmap_data->nr_parts) {
printk(KERN_NOTICE "Using physmap partition information\n");
mtd_device_register(info->cmtd, physmap_data->parts,
physmap_data->nr_parts);
return 0;
}
mtd_device_register(info->cmtd, NULL, 0);
mtd_device_parse_register(info->cmtd, part_probe_types, 0,
physmap_data->parts, physmap_data->nr_parts);
return 0;
err_out:
@ -245,21 +226,6 @@ static struct platform_device physmap_flash = {
.num_resources = 1,
.resource = &physmap_flash_resource,
};
void physmap_configure(unsigned long addr, unsigned long size,
int bankwidth, void (*set_vpp)(struct map_info *, int))
{
physmap_flash_resource.start = addr;
physmap_flash_resource.end = addr + size - 1;
physmap_flash_data.width = bankwidth;
physmap_flash_data.set_vpp = set_vpp;
}
void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
{
physmap_flash_data.nr_parts = num_parts;
physmap_flash_data.parts = parts;
}
#endif
static int __init physmap_init(void)

View File

@ -34,58 +34,10 @@ struct of_flash_list {
struct of_flash {
struct mtd_info *cmtd;
struct mtd_partition *parts;
int list_size; /* number of elements in of_flash_list */
struct of_flash_list list[0];
};
#define OF_FLASH_PARTS(info) ((info)->parts)
static int parse_obsolete_partitions(struct platform_device *dev,
struct of_flash *info,
struct device_node *dp)
{
int i, plen, nr_parts;
const struct {
__be32 offset, len;
} *part;
const char *names;
part = of_get_property(dp, "partitions", &plen);
if (!part)
return 0; /* No partitions found */
dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n");
nr_parts = plen / sizeof(part[0]);
info->parts = kzalloc(nr_parts * sizeof(*info->parts), GFP_KERNEL);
if (!info->parts)
return -ENOMEM;
names = of_get_property(dp, "partition-names", &plen);
for (i = 0; i < nr_parts; i++) {
info->parts[i].offset = be32_to_cpu(part->offset);
info->parts[i].size = be32_to_cpu(part->len) & ~1;
if (be32_to_cpu(part->len) & 1) /* bit 0 set signifies read only partition */
info->parts[i].mask_flags = MTD_WRITEABLE;
if (names && (plen > 0)) {
int len = strlen(names) + 1;
info->parts[i].name = (char *)names;
plen -= len;
names += len;
} else {
info->parts[i].name = "unnamed";
}
part++;
}
return nr_parts;
}
static int of_flash_remove(struct platform_device *dev)
{
struct of_flash *info;
@ -101,11 +53,8 @@ static int of_flash_remove(struct platform_device *dev)
mtd_concat_destroy(info->cmtd);
}
if (info->cmtd) {
if (OF_FLASH_PARTS(info))
kfree(OF_FLASH_PARTS(info));
if (info->cmtd)
mtd_device_unregister(info->cmtd);
}
for (i = 0; i < info->list_size; i++) {
if (info->list[i].mtd)
@ -165,7 +114,8 @@ static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev,
specifies the list of partition probers to use. If none is given then the
default is use. These take precedence over other device tree
information. */
static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", NULL };
static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot",
"ofpart", "ofoldpart", NULL };
static const char ** __devinit of_get_probes(struct device_node *dp)
{
const char *cp;
@ -218,6 +168,7 @@ static int __devinit of_flash_probe(struct platform_device *dev)
int reg_tuple_size;
struct mtd_info **mtd_list = NULL;
resource_size_t res_size;
struct mtd_part_parser_data ppdata;
match = of_match_device(of_flash_match, &dev->dev);
if (!match)
@ -331,29 +282,12 @@ static int __devinit of_flash_probe(struct platform_device *dev)
if (err)
goto err_out;
ppdata.of_node = dp;
part_probe_types = of_get_probes(dp);
err = parse_mtd_partitions(info->cmtd, part_probe_types,
&info->parts, 0);
if (err < 0) {
of_free_probes(part_probe_types);
goto err_out;
}
mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata,
NULL, 0);
of_free_probes(part_probe_types);
if (err == 0) {
err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
if (err < 0)
goto err_out;
}
if (err == 0) {
err = parse_obsolete_partitions(dev, info, dp);
if (err < 0)
goto err_out;
}
mtd_device_register(info->cmtd, info->parts, err);
kfree(mtd_list);
return 0;

View File

@ -44,8 +44,6 @@ struct platram_info {
struct device *dev;
struct mtd_info *mtd;
struct map_info map;
struct mtd_partition *partitions;
bool free_partitions;
struct resource *area;
struct platdata_mtd_ram *pdata;
};
@ -95,10 +93,6 @@ static int platram_remove(struct platform_device *pdev)
if (info->mtd) {
mtd_device_unregister(info->mtd);
if (info->partitions) {
if (info->free_partitions)
kfree(info->partitions);
}
map_destroy(info->mtd);
}
@ -228,21 +222,8 @@ static int platram_probe(struct platform_device *pdev)
/* check to see if there are any available partitions, or wether
* to add this device whole */
if (!pdata->nr_partitions) {
/* try to probe using the supplied probe type */
if (pdata->probes) {
err = parse_mtd_partitions(info->mtd, pdata->probes,
&info->partitions, 0);
info->free_partitions = 1;
if (err > 0)
err = mtd_device_register(info->mtd,
info->partitions, err);
}
}
/* use the static mapping */
else
err = mtd_device_register(info->mtd, pdata->partitions,
pdata->nr_partitions);
err = mtd_device_parse_register(info->mtd, pdata->probes, 0,
pdata->partitions, pdata->nr_partitions);
if (!err)
dev_info(&pdev->dev, "registered mtd device\n");

View File

@ -41,8 +41,6 @@ static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from,
}
struct pxa2xx_flash_info {
struct mtd_partition *parts;
int nr_parts;
struct mtd_info *mtd;
struct map_info map;
};
@ -55,9 +53,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
{
struct flash_platform_data *flash = pdev->dev.platform_data;
struct pxa2xx_flash_info *info;
struct mtd_partition *parts;
struct resource *res;
int ret = 0;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
@ -71,8 +67,6 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
info->map.bankwidth = flash->width;
info->map.phys = res->start;
info->map.size = resource_size(res);
info->parts = flash->parts;
info->nr_parts = flash->nr_parts;
info->map.virt = ioremap(info->map.phys, info->map.size);
if (!info->map.virt) {
@ -104,18 +98,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
}
info->mtd->owner = THIS_MODULE;
ret = parse_mtd_partitions(info->mtd, probes, &parts, 0);
if (ret > 0) {
info->nr_parts = ret;
info->parts = parts;
}
if (!info->nr_parts)
printk("Registering %s as whole device\n",
info->map.name);
mtd_device_register(info->mtd, info->parts, info->nr_parts);
mtd_device_parse_register(info->mtd, probes, 0, NULL, 0);
platform_set_drvdata(pdev, info);
return 0;
@ -133,7 +116,6 @@ static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
iounmap(info->map.virt);
if (info->map.cached)
iounmap(info->map.cached);
kfree(info->parts);
kfree(info);
return 0;
}

View File

@ -25,8 +25,6 @@
struct rbtx4939_flash_info {
struct mtd_info *mtd;
struct map_info map;
int nr_parts;
struct mtd_partition *parts;
};
static int rbtx4939_flash_remove(struct platform_device *dev)
@ -41,8 +39,6 @@ static int rbtx4939_flash_remove(struct platform_device *dev)
if (info->mtd) {
struct rbtx4939_flash_data *pdata = dev->dev.platform_data;
if (info->nr_parts)
kfree(info->parts);
mtd_device_unregister(info->mtd);
map_destroy(info->mtd);
}
@ -50,7 +46,6 @@ static int rbtx4939_flash_remove(struct platform_device *dev)
}
static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
static const char *part_probe_types[] = { "cmdlinepart", NULL };
static int rbtx4939_flash_probe(struct platform_device *dev)
{
@ -107,22 +102,11 @@ static int rbtx4939_flash_probe(struct platform_device *dev)
info->mtd->owner = THIS_MODULE;
if (err)
goto err_out;
err = mtd_device_parse_register(info->mtd, NULL, 0,
pdata->parts, pdata->nr_parts);
err = parse_mtd_partitions(info->mtd, part_probe_types,
&info->parts, 0);
if (err > 0) {
mtd_device_register(info->mtd, info->parts, err);
info->nr_parts = err;
return 0;
}
if (pdata->nr_parts) {
pr_notice("Using rbtx4939 partition information\n");
mtd_device_register(info->mtd, pdata->parts, pdata->nr_parts);
return 0;
}
mtd_device_register(info->mtd, NULL, 0);
if (err)
goto err_out;
return 0;
err_out:

View File

@ -131,10 +131,8 @@ struct sa_subdev_info {
};
struct sa_info {
struct mtd_partition *parts;
struct mtd_info *mtd;
int num_subdev;
unsigned int nr_parts;
struct sa_subdev_info subdev[0];
};
@ -231,8 +229,6 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla
mtd_concat_destroy(info->mtd);
}
kfree(info->parts);
for (i = info->num_subdev - 1; i >= 0; i--)
sa1100_destroy_subdev(&info->subdev[i]);
kfree(info);
@ -341,10 +337,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
{
struct flash_platform_data *plat = pdev->dev.platform_data;
struct mtd_partition *parts;
const char *part_type = NULL;
struct sa_info *info;
int err, nr_parts = 0;
int err;
if (!plat)
return -ENODEV;
@ -358,26 +352,8 @@ static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
/*
* Partition selection stuff.
*/
nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0);
if (nr_parts > 0) {
info->parts = parts;
part_type = "dynamic";
} else {
parts = plat->parts;
nr_parts = plat->nr_parts;
part_type = "static";
}
if (nr_parts == 0)
printk(KERN_NOTICE "SA1100 flash: no partition info "
"available, registering whole flash\n");
else
printk(KERN_NOTICE "SA1100 flash: using %s partition "
"definition\n", part_type);
mtd_device_register(info->mtd, parts, nr_parts);
info->nr_parts = nr_parts;
mtd_device_parse_register(info->mtd, part_probes, 0,
plat->parts, plat->nr_parts);
platform_set_drvdata(pdev, info);
err = 0;

View File

@ -19,8 +19,6 @@
static struct mtd_info *flash_mtd;
static struct mtd_info *eprom_mtd;
static struct mtd_partition *parsed_parts;
struct map_info soleng_eprom_map = {
.name = "Solution Engine EPROM",
.size = 0x400000,
@ -51,12 +49,14 @@ static struct mtd_partition superh_se_partitions[] = {
.size = MTDPART_SIZ_FULL,
}
};
#define NUM_PARTITIONS ARRAY_SIZE(superh_se_partitions)
#else
#define superh_se_partitions NULL
#define NUM_PARTITIONS 0
#endif /* CONFIG_MTD_SUPERH_RESERVE */
static int __init init_soleng_maps(void)
{
int nr_parts = 0;
/* First probe at offset 0 */
soleng_flash_map.phys = 0;
soleng_flash_map.virt = (void __iomem *)P2SEGADDR(0);
@ -92,21 +92,8 @@ static int __init init_soleng_maps(void)
mtd_device_register(eprom_mtd, NULL, 0);
}
nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0);
#ifdef CONFIG_MTD_SUPERH_RESERVE
if (nr_parts <= 0) {
printk(KERN_NOTICE "Using configured partition at 0x%08x.\n",
CONFIG_MTD_SUPERH_RESERVE);
parsed_parts = superh_se_partitions;
nr_parts = sizeof(superh_se_partitions)/sizeof(*parsed_parts);
}
#endif /* CONFIG_MTD_SUPERH_RESERVE */
if (nr_parts > 0)
mtd_device_register(flash_mtd, parsed_parts, nr_parts);
else
mtd_device_register(flash_mtd, NULL, 0);
mtd_device_parse_register(flash_mtd, probes, 0,
superh_se_partitions, NUM_PARTITIONS);
return 0;
}
@ -118,10 +105,7 @@ static void __exit cleanup_soleng_maps(void)
map_destroy(eprom_mtd);
}
if (parsed_parts)
mtd_device_unregister(flash_mtd);
else
mtd_device_unregister(flash_mtd);
mtd_device_unregister(flash_mtd);
map_destroy(flash_mtd);
}

View File

@ -20,7 +20,6 @@
#include <asm/immap_cpm2.h>
static struct mtd_info *sbcmtd[3];
static struct mtd_partition *sbcmtd_parts[3];
struct map_info sbc82xx_flash_map[3] = {
{.name = "Boot flash"},
@ -101,6 +100,7 @@ static int __init init_sbc82xx_flash(void)
for (i=0; i<3; i++) {
int8_t flashcs[3] = { 0, 6, 1 };
int nr_parts;
struct mtd_partition *defparts;
printk(KERN_NOTICE "PowerQUICC II %s (%ld MiB on CS%d",
sbc82xx_flash_map[i].name,
@ -113,7 +113,8 @@ static int __init init_sbc82xx_flash(void)
}
printk(" at %08lx)\n", sbc82xx_flash_map[i].phys);
sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys, sbc82xx_flash_map[i].size);
sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys,
sbc82xx_flash_map[i].size);
if (!sbc82xx_flash_map[i].virt) {
printk("Failed to ioremap\n");
@ -129,24 +130,20 @@ static int __init init_sbc82xx_flash(void)
sbcmtd[i]->owner = THIS_MODULE;
nr_parts = parse_mtd_partitions(sbcmtd[i], part_probes,
&sbcmtd_parts[i], 0);
if (nr_parts > 0) {
mtd_device_register(sbcmtd[i], sbcmtd_parts[i],
nr_parts);
continue;
}
/* No partitioning detected. Use default */
if (i == 2) {
mtd_device_register(sbcmtd[i], NULL, 0);
defparts = NULL;
nr_parts = 0;
} else if (i == bigflash) {
mtd_device_register(sbcmtd[i], bigflash_parts,
ARRAY_SIZE(bigflash_parts));
defparts = bigflash_parts;
nr_parts = ARRAY_SIZE(bigflash_parts);
} else {
mtd_device_register(sbcmtd[i], smallflash_parts,
ARRAY_SIZE(smallflash_parts));
defparts = smallflash_parts;
nr_parts = ARRAY_SIZE(smallflash_parts);
}
mtd_device_parse_register(sbcmtd[i], part_probes, 0,
defparts, nr_parts);
}
return 0;
}
@ -159,12 +156,8 @@ static void __exit cleanup_sbc82xx_flash(void)
if (!sbcmtd[i])
continue;
if (i<2 || sbcmtd_parts[i])
mtd_device_unregister(sbcmtd[i]);
else
mtd_device_unregister(sbcmtd[i]);
mtd_device_unregister(sbcmtd[i]);
kfree(sbcmtd_parts[i]);
map_destroy(sbcmtd[i]);
iounmap((void *)sbc82xx_flash_map[i].virt);

View File

@ -426,6 +426,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
new->rq->queuedata = new;
blk_queue_logical_block_size(new->rq, tr->blksize);
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, new->rq);
if (tr->discard) {
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, new->rq);
new->rq->limits.max_discard_sectors = UINT_MAX;

View File

@ -44,7 +44,7 @@ struct mtdblk_dev {
enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
};
static struct mutex mtdblks_lock;
static DEFINE_MUTEX(mtdblks_lock);
/*
* Cache stuff...
@ -119,7 +119,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
if (mtdblk->cache_state != STATE_DIRTY)
return 0;
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" "
pr_debug("mtdblock: writing cached data for \"%s\" "
"at 0x%lx, size 0x%x\n", mtd->name,
mtdblk->cache_offset, mtdblk->cache_size);
@ -148,7 +148,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
size_t retlen;
int ret;
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
pr_debug("mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
mtd->name, pos, len);
if (!sect_size)
@ -218,7 +218,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
size_t retlen;
int ret;
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
mtd->name, pos, len);
if (!sect_size)
@ -283,7 +283,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
{
struct mtdblk_dev *mtdblk = container_of(mbd, struct mtdblk_dev, mbd);
DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
pr_debug("mtdblock_open\n");
mutex_lock(&mtdblks_lock);
if (mtdblk->count) {
@ -303,7 +303,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
mutex_unlock(&mtdblks_lock);
DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
pr_debug("ok\n");
return 0;
}
@ -312,7 +312,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
{
struct mtdblk_dev *mtdblk = container_of(mbd, struct mtdblk_dev, mbd);
DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
pr_debug("mtdblock_release\n");
mutex_lock(&mtdblks_lock);
@ -329,7 +329,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
mutex_unlock(&mtdblks_lock);
DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
pr_debug("ok\n");
return 0;
}
@ -389,8 +389,6 @@ static struct mtd_blktrans_ops mtdblock_tr = {
static int __init init_mtdblock(void)
{
mutex_init(&mtdblks_lock);
return register_mtd_blktrans(&mtdblock_tr);
}

View File

@ -43,7 +43,7 @@ static struct vfsmount *mtd_inode_mnt __read_mostly;
/*
* Data structure to hold the pointer to the mtd device as well
* as mode information ofr various use cases.
* as mode information of various use cases.
*/
struct mtd_file_info {
struct mtd_info *mtd;
@ -86,7 +86,7 @@ static int mtd_open(struct inode *inode, struct file *file)
struct mtd_file_info *mfi;
struct inode *mtd_ino;
DEBUG(MTD_DEBUG_LEVEL0, "MTD_open\n");
pr_debug("MTD_open\n");
/* You can't open the RO devices RW */
if ((file->f_mode & FMODE_WRITE) && (minor & 1))
@ -151,7 +151,7 @@ static int mtd_close(struct inode *inode, struct file *file)
struct mtd_file_info *mfi = file->private_data;
struct mtd_info *mtd = mfi->mtd;
DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
pr_debug("MTD_close\n");
/* Only sync if opened RW */
if ((file->f_mode & FMODE_WRITE) && mtd->sync)
@ -195,7 +195,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
size_t size = count;
char *kbuf;
DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
pr_debug("MTD_read\n");
if (*ppos + count > mtd->size)
count = mtd->size - *ppos;
@ -211,17 +211,17 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
len = min_t(size_t, count, size);
switch (mfi->mode) {
case MTD_MODE_OTP_FACTORY:
case MTD_FILE_MODE_OTP_FACTORY:
ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
break;
case MTD_MODE_OTP_USER:
case MTD_FILE_MODE_OTP_USER:
ret = mtd->read_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
break;
case MTD_MODE_RAW:
case MTD_FILE_MODE_RAW:
{
struct mtd_oob_ops ops;
ops.mode = MTD_OOB_RAW;
ops.mode = MTD_OPS_RAW;
ops.datbuf = kbuf;
ops.oobbuf = NULL;
ops.len = len;
@ -233,16 +233,16 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
default:
ret = mtd->read(mtd, *ppos, len, &retlen, kbuf);
}
/* Nand returns -EBADMSG on ecc errors, but it returns
/* Nand returns -EBADMSG on ECC errors, but it returns
* the data. For our userspace tools it is important
* to dump areas with ecc errors !
* to dump areas with ECC errors!
* For kernel internal usage it also might return -EUCLEAN
* to signal the caller that a bitflip has occurred and has
* been corrected by the ECC algorithm.
* Userspace software which accesses NAND this way
* must be aware of the fact that it deals with NAND
*/
if (!ret || (ret == -EUCLEAN) || (ret == -EBADMSG)) {
if (!ret || mtd_is_bitflip_or_eccerr(ret)) {
*ppos += retlen;
if (copy_to_user(buf, kbuf, retlen)) {
kfree(kbuf);
@ -278,7 +278,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
int ret=0;
int len;
DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
pr_debug("MTD_write\n");
if (*ppos == mtd->size)
return -ENOSPC;
@ -302,10 +302,10 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
}
switch (mfi->mode) {
case MTD_MODE_OTP_FACTORY:
case MTD_FILE_MODE_OTP_FACTORY:
ret = -EROFS;
break;
case MTD_MODE_OTP_USER:
case MTD_FILE_MODE_OTP_USER:
if (!mtd->write_user_prot_reg) {
ret = -EOPNOTSUPP;
break;
@ -313,13 +313,14 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
ret = mtd->write_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
break;
case MTD_MODE_RAW:
case MTD_FILE_MODE_RAW:
{
struct mtd_oob_ops ops;
ops.mode = MTD_OOB_RAW;
ops.mode = MTD_OPS_RAW;
ops.datbuf = kbuf;
ops.oobbuf = NULL;
ops.ooboffs = 0;
ops.len = len;
ret = mtd->write_oob(mtd, *ppos, &ops);
@ -367,13 +368,13 @@ static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
if (!mtd->read_fact_prot_reg)
ret = -EOPNOTSUPP;
else
mfi->mode = MTD_MODE_OTP_FACTORY;
mfi->mode = MTD_FILE_MODE_OTP_FACTORY;
break;
case MTD_OTP_USER:
if (!mtd->read_fact_prot_reg)
ret = -EOPNOTSUPP;
else
mfi->mode = MTD_MODE_OTP_USER;
mfi->mode = MTD_FILE_MODE_OTP_USER;
break;
default:
ret = -EINVAL;
@ -390,6 +391,7 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
uint64_t start, uint32_t length, void __user *ptr,
uint32_t __user *retp)
{
struct mtd_file_info *mfi = file->private_data;
struct mtd_oob_ops ops;
uint32_t retlen;
int ret = 0;
@ -409,9 +411,10 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
return ret;
ops.ooblen = length;
ops.ooboffs = start & (mtd->oobsize - 1);
ops.ooboffs = start & (mtd->writesize - 1);
ops.datbuf = NULL;
ops.mode = MTD_OOB_PLACE;
ops.mode = (mfi->mode == MTD_FILE_MODE_RAW) ? MTD_OPS_RAW :
MTD_OPS_PLACE_OOB;
if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
return -EINVAL;
@ -420,7 +423,7 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
if (IS_ERR(ops.oobbuf))
return PTR_ERR(ops.oobbuf);
start &= ~((uint64_t)mtd->oobsize - 1);
start &= ~((uint64_t)mtd->writesize - 1);
ret = mtd->write_oob(mtd, start, &ops);
if (ops.oobretlen > 0xFFFFFFFFU)
@ -433,9 +436,11 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
return ret;
}
static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
uint32_t length, void __user *ptr, uint32_t __user *retp)
static int mtd_do_readoob(struct file *file, struct mtd_info *mtd,
uint64_t start, uint32_t length, void __user *ptr,
uint32_t __user *retp)
{
struct mtd_file_info *mfi = file->private_data;
struct mtd_oob_ops ops;
int ret = 0;
@ -451,9 +456,10 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
return ret;
ops.ooblen = length;
ops.ooboffs = start & (mtd->oobsize - 1);
ops.ooboffs = start & (mtd->writesize - 1);
ops.datbuf = NULL;
ops.mode = MTD_OOB_PLACE;
ops.mode = (mfi->mode == MTD_FILE_MODE_RAW) ? MTD_OPS_RAW :
MTD_OPS_PLACE_OOB;
if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
return -EINVAL;
@ -462,7 +468,7 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
if (!ops.oobbuf)
return -ENOMEM;
start &= ~((uint64_t)mtd->oobsize - 1);
start &= ~((uint64_t)mtd->writesize - 1);
ret = mtd->read_oob(mtd, start, &ops);
if (put_user(ops.oobretlen, retp))
@ -472,13 +478,29 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
ret = -EFAULT;
kfree(ops.oobbuf);
/*
* NAND returns -EBADMSG on ECC errors, but it returns the OOB
* data. For our userspace tools it is important to dump areas
* with ECC errors!
* For kernel internal usage it also might return -EUCLEAN
* to signal the caller that a bitflip has occured and has
* been corrected by the ECC algorithm.
*
* Note: currently the standard NAND function, nand_read_oob_std,
* does not calculate ECC for the OOB area, so do not rely on
* this behavior unless you have replaced it with your own.
*/
if (mtd_is_bitflip_or_eccerr(ret))
return 0;
return ret;
}
/*
* Copies (and truncates, if necessary) data from the larger struct,
* nand_ecclayout, to the smaller, deprecated layout struct,
* nand_ecclayout_user. This is necessary only to suppport the deprecated
* nand_ecclayout_user. This is necessary only to support the deprecated
* API ioctl ECCGETLAYOUT while allowing all new functionality to use
* nand_ecclayout flexibly (i.e. the struct may change size in new
* releases without requiring major rewrites).
@ -544,6 +566,55 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd,
}
}
static int mtd_write_ioctl(struct mtd_info *mtd,
struct mtd_write_req __user *argp)
{
struct mtd_write_req req;
struct mtd_oob_ops ops;
void __user *usr_data, *usr_oob;
int ret;
if (copy_from_user(&req, argp, sizeof(req)) ||
!access_ok(VERIFY_READ, req.usr_data, req.len) ||
!access_ok(VERIFY_READ, req.usr_oob, req.ooblen))
return -EFAULT;
if (!mtd->write_oob)
return -EOPNOTSUPP;
ops.mode = req.mode;
ops.len = (size_t)req.len;
ops.ooblen = (size_t)req.ooblen;
ops.ooboffs = 0;
usr_data = (void __user *)(uintptr_t)req.usr_data;
usr_oob = (void __user *)(uintptr_t)req.usr_oob;
if (req.usr_data) {
ops.datbuf = memdup_user(usr_data, ops.len);
if (IS_ERR(ops.datbuf))
return PTR_ERR(ops.datbuf);
} else {
ops.datbuf = NULL;
}
if (req.usr_oob) {
ops.oobbuf = memdup_user(usr_oob, ops.ooblen);
if (IS_ERR(ops.oobbuf)) {
kfree(ops.datbuf);
return PTR_ERR(ops.oobbuf);
}
} else {
ops.oobbuf = NULL;
}
ret = mtd->write_oob(mtd, (loff_t)req.start, &ops);
kfree(ops.datbuf);
kfree(ops.oobbuf);
return ret;
}
static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
{
struct mtd_file_info *mfi = file->private_data;
@ -553,7 +624,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
u_long size;
struct mtd_info_user info;
DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");
pr_debug("MTD_ioctl\n");
size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
if (cmd & IOC_IN) {
@ -601,8 +672,8 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
info.erasesize = mtd->erasesize;
info.writesize = mtd->writesize;
info.oobsize = mtd->oobsize;
/* The below fields are obsolete */
info.ecctype = -1;
/* The below field is obsolete */
info.padding = 0;
if (copy_to_user(argp, &info, sizeof(struct mtd_info_user)))
return -EFAULT;
break;
@ -698,7 +769,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
if (copy_from_user(&buf, argp, sizeof(buf)))
ret = -EFAULT;
else
ret = mtd_do_readoob(mtd, buf.start, buf.length,
ret = mtd_do_readoob(file, mtd, buf.start, buf.length,
buf.ptr, &buf_user->start);
break;
}
@ -725,12 +796,19 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
if (copy_from_user(&buf, argp, sizeof(buf)))
ret = -EFAULT;
else
ret = mtd_do_readoob(mtd, buf.start, buf.length,
ret = mtd_do_readoob(file, mtd, buf.start, buf.length,
(void __user *)(uintptr_t)buf.usr_ptr,
&buf_user->length);
break;
}
case MEMWRITE:
{
ret = mtd_write_ioctl(mtd,
(struct mtd_write_req __user *)arg);
break;
}
case MEMLOCK:
{
struct erase_info_user einfo;
@ -827,7 +905,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
if (copy_from_user(&mode, argp, sizeof(int)))
return -EFAULT;
mfi->mode = MTD_MODE_NORMAL;
mfi->mode = MTD_FILE_MODE_NORMAL;
ret = otp_select_filemode(mfi, mode);
@ -843,11 +921,11 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
return -ENOMEM;
ret = -EOPNOTSUPP;
switch (mfi->mode) {
case MTD_MODE_OTP_FACTORY:
case MTD_FILE_MODE_OTP_FACTORY:
if (mtd->get_fact_prot_info)
ret = mtd->get_fact_prot_info(mtd, buf, 4096);
break;
case MTD_MODE_OTP_USER:
case MTD_FILE_MODE_OTP_USER:
if (mtd->get_user_prot_info)
ret = mtd->get_user_prot_info(mtd, buf, 4096);
break;
@ -871,7 +949,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
{
struct otp_info oinfo;
if (mfi->mode != MTD_MODE_OTP_USER)
if (mfi->mode != MTD_FILE_MODE_OTP_USER)
return -EINVAL;
if (copy_from_user(&oinfo, argp, sizeof(oinfo)))
return -EFAULT;
@ -882,7 +960,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
}
#endif
/* This ioctl is being deprecated - it truncates the ecc layout */
/* This ioctl is being deprecated - it truncates the ECC layout */
case ECCGETLAYOUT:
{
struct nand_ecclayout_user *usrlay;
@ -915,17 +993,17 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
mfi->mode = 0;
switch(arg) {
case MTD_MODE_OTP_FACTORY:
case MTD_MODE_OTP_USER:
case MTD_FILE_MODE_OTP_FACTORY:
case MTD_FILE_MODE_OTP_USER:
ret = otp_select_filemode(mfi, arg);
break;
case MTD_MODE_RAW:
case MTD_FILE_MODE_RAW:
if (!mtd->read_oob || !mtd->write_oob)
return -EOPNOTSUPP;
mfi->mode = arg;
case MTD_MODE_NORMAL:
case MTD_FILE_MODE_NORMAL:
break;
default:
ret = -EINVAL;
@ -1011,7 +1089,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
if (copy_from_user(&buf, argp, sizeof(buf)))
ret = -EFAULT;
else
ret = mtd_do_readoob(mtd, buf.start,
ret = mtd_do_readoob(file, mtd, buf.start,
buf.length, compat_ptr(buf.ptr),
&buf_user->start);
break;

View File

@ -95,10 +95,10 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
/* Save information about bitflips! */
if (unlikely(err)) {
if (err == -EBADMSG) {
if (mtd_is_eccerr(err)) {
mtd->ecc_stats.failed++;
ret = err;
} else if (err == -EUCLEAN) {
} else if (mtd_is_bitflip(err)) {
mtd->ecc_stats.corrected++;
/* Do not overwrite -EBADMSG !! */
if (!ret)
@ -279,10 +279,10 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
/* Save information about bitflips! */
if (unlikely(err)) {
if (err == -EBADMSG) {
if (mtd_is_eccerr(err)) {
mtd->ecc_stats.failed++;
ret = err;
} else if (err == -EUCLEAN) {
} else if (mtd_is_bitflip(err)) {
mtd->ecc_stats.corrected++;
/* Do not overwrite -EBADMSG !! */
if (!ret)
@ -770,7 +770,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
/*
* Set up the new "super" device's MTD object structure, check for
* incompatibilites between the subdevices.
* incompatibilities between the subdevices.
*/
concat->mtd.type = subdev[0]->type;
concat->mtd.flags = subdev[0]->flags;

View File

@ -362,7 +362,7 @@ int add_mtd_device(struct mtd_info *mtd)
MTD_DEVT(i) + 1,
NULL, "mtd%dro", i);
DEBUG(0, "mtd: Giving out device %d to %s\n", i, mtd->name);
pr_debug("mtd: Giving out device %d to %s\n", i, mtd->name);
/* No need to get a refcount on the module containing
the notifier, since we hold the mtd_table_mutex */
list_for_each_entry(not, &mtd_notifiers, list)
@ -429,27 +429,63 @@ out_error:
}
/**
* mtd_device_register - register an MTD device.
* mtd_device_parse_register - parse partitions and register an MTD device.
*
* @master: the MTD device to register
* @parts: the partitions to register - only valid if nr_parts > 0
* @nr_parts: the number of partitions in parts. If zero then the full MTD
* device is registered
* @mtd: the MTD device to register
* @types: the list of MTD partition probes to try, see
* 'parse_mtd_partitions()' for more information
* @parser_data: MTD partition parser-specific data
* @parts: fallback partition information to register, if parsing fails;
* only valid if %nr_parts > %0
* @nr_parts: the number of partitions in parts, if zero then the full
* MTD device is registered if no partition info is found
*
* Register an MTD device with the system and optionally, a number of
* partitions. If nr_parts is 0 then the whole device is registered, otherwise
* only the partitions are registered. To register both the full device *and*
* the partitions, call mtd_device_register() twice, once with nr_parts == 0
* and once equal to the number of partitions.
* This function aggregates MTD partitions parsing (done by
* 'parse_mtd_partitions()') and MTD device and partitions registering. It
* basically follows the most common pattern found in many MTD drivers:
*
* * It first tries to probe partitions on MTD device @mtd using parsers
* specified in @types (if @types is %NULL, then the default list of parsers
* is used, see 'parse_mtd_partitions()' for more information). If none are
* found this functions tries to fallback to information specified in
* @parts/@nr_parts.
* * If any partitioning info was found, this function registers the found
* partitions.
* * If no partitions were found this function just registers the MTD device
* @mtd and exits.
*
* Returns zero in case of success and a negative error code in case of failure.
*/
int mtd_device_register(struct mtd_info *master,
const struct mtd_partition *parts,
int nr_parts)
int mtd_device_parse_register(struct mtd_info *mtd, const char **types,
struct mtd_part_parser_data *parser_data,
const struct mtd_partition *parts,
int nr_parts)
{
return parts ? add_mtd_partitions(master, parts, nr_parts) :
add_mtd_device(master);
int err;
struct mtd_partition *real_parts;
err = parse_mtd_partitions(mtd, types, &real_parts, parser_data);
if (err <= 0 && nr_parts && parts) {
real_parts = kmemdup(parts, sizeof(*parts) * nr_parts,
GFP_KERNEL);
if (!real_parts)
err = -ENOMEM;
else
err = nr_parts;
}
if (err > 0) {
err = add_mtd_partitions(mtd, real_parts, err);
kfree(real_parts);
} else if (err == 0) {
err = add_mtd_device(mtd);
if (err == 1)
err = -ENODEV;
}
return err;
}
EXPORT_SYMBOL_GPL(mtd_device_register);
EXPORT_SYMBOL_GPL(mtd_device_parse_register);
/**
* mtd_device_unregister - unregister an existing MTD device.

View File

@ -15,6 +15,9 @@ extern int del_mtd_device(struct mtd_info *mtd);
extern int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *,
int);
extern int del_mtd_partitions(struct mtd_info *);
extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
struct mtd_partition **pparts,
struct mtd_part_parser_data *data);
#define mtd_for_each_device(mtd) \
for ((mtd) = __mtd_next_device(0); \

View File

@ -258,7 +258,7 @@ static void find_next_position(struct mtdoops_context *cxt)
ret = mtd->read(mtd, page * record_size, MTDOOPS_HEADER_SIZE,
&retlen, (u_char *) &count[0]);
if (retlen != MTDOOPS_HEADER_SIZE ||
(ret < 0 && ret != -EUCLEAN)) {
(ret < 0 && !mtd_is_bitflip(ret))) {
printk(KERN_ERR "mtdoops: read failure at %ld (%td of %d read), err %d\n",
page * record_size, retlen,
MTDOOPS_HEADER_SIZE, ret);

View File

@ -73,9 +73,9 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
res = part->master->read(part->master, from + part->offset,
len, retlen, buf);
if (unlikely(res)) {
if (res == -EUCLEAN)
if (mtd_is_bitflip(res))
mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
if (res == -EBADMSG)
if (mtd_is_eccerr(res))
mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
}
return res;
@ -130,7 +130,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
if (ops->oobbuf) {
size_t len, pages;
if (ops->mode == MTD_OOB_AUTO)
if (ops->mode == MTD_OPS_AUTO_OOB)
len = mtd->oobavail;
else
len = mtd->oobsize;
@ -142,9 +142,9 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
res = part->master->read_oob(part->master, from + part->offset, ops);
if (unlikely(res)) {
if (res == -EUCLEAN)
if (mtd_is_bitflip(res))
mtd->ecc_stats.corrected++;
if (res == -EBADMSG)
if (mtd_is_eccerr(res))
mtd->ecc_stats.failed++;
}
return res;
@ -479,6 +479,19 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
(unsigned long long)cur_offset, (unsigned long long)slave->offset);
}
}
if (slave->offset == MTDPART_OFS_RETAIN) {
slave->offset = cur_offset;
if (master->size - slave->offset >= slave->mtd.size) {
slave->mtd.size = master->size - slave->offset
- slave->mtd.size;
} else {
printk(KERN_ERR "mtd partition \"%s\" doesn't have enough space: %#llx < %#llx, disabled\n",
part->name, master->size - slave->offset,
slave->mtd.size);
/* register to preserve ordering */
goto out_register;
}
}
if (slave->mtd.size == MTDPART_SIZ_FULL)
slave->mtd.size = master->size - slave->offset;
@ -693,6 +706,8 @@ static struct mtd_part_parser *get_partition_parser(const char *name)
return ret;
}
#define put_partition_parser(p) do { module_put((p)->owner); } while (0)
int register_mtd_parser(struct mtd_part_parser *p)
{
spin_lock(&part_parser_lock);
@ -712,19 +727,51 @@ int deregister_mtd_parser(struct mtd_part_parser *p)
}
EXPORT_SYMBOL_GPL(deregister_mtd_parser);
/*
* Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
* are changing this array!
*/
static const char *default_mtd_part_types[] = {
"cmdlinepart",
"ofpart",
NULL
};
/**
* parse_mtd_partitions - parse MTD partitions
* @master: the master partition (describes whole MTD device)
* @types: names of partition parsers to try or %NULL
* @pparts: array of partitions found is returned here
* @data: MTD partition parser-specific data
*
* This function tries to find partition on MTD device @master. It uses MTD
* partition parsers, specified in @types. However, if @types is %NULL, then
* the default list of parsers is used. The default list contains only the
* "cmdlinepart" and "ofpart" parsers ATM.
*
* This function may return:
* o a negative error code in case of failure
* o zero if no partitions were found
* o a positive number of found partitions, in which case on exit @pparts will
* point to an array containing this number of &struct mtd_info objects.
*/
int parse_mtd_partitions(struct mtd_info *master, const char **types,
struct mtd_partition **pparts, unsigned long origin)
struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
struct mtd_part_parser *parser;
int ret = 0;
if (!types)
types = default_mtd_part_types;
for ( ; ret <= 0 && *types; types++) {
parser = get_partition_parser(*types);
if (!parser && !request_module("%s", *types))
parser = get_partition_parser(*types);
if (!parser)
continue;
ret = (*parser->parse_fn)(master, pparts, origin);
ret = (*parser->parse_fn)(master, pparts, data);
if (ret > 0) {
printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
ret, parser->name, master->name);
@ -733,7 +780,6 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
}
return ret;
}
EXPORT_SYMBOL_GPL(parse_mtd_partitions);
int mtd_is_partition(struct mtd_info *mtd)
{

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