Merge tag 'nand/for-4.20' of git://git.infradead.org/linux-mtd into mtd/next
NAND core changes: - Two batchs of cleanups of the NAND API, including: * Deprecating a lot of interfaces (now replaced by ->exec_op()). * Moving code in separate drivers (JEDEC, ONFI), in private files (internals), in platform drivers, etc. * Functions/structures reordering. * Exclusive use of the nand_chip structure instead of the MTD one all across the subsystem. - Addition of the nand_wait_readrdy/rdy_op() helpers. Raw NAND controllers drivers changes: - Various coccinelle patches. - Marvell: * Use regmap_update_bits() for syscon access. * More documentation. * BCH failure path rework. * More layouts to be supported. * IRQ handler complete() condition fixed. - Fsl_ifc: * SRAM initialization fixed for newer controller versions. - Denali: * Fix licenses mismatch and use a SPDX tag. * Set SPARE_AREA_SKIP_BYTES register to 8 if unset. - Qualcomm: * Do not include dma-direct.h. - Docg4: * Removed. - Ams-delta: * Use of a GPIO lookup table * Internal machinery changes. Raw NAND chip drivers changes: - Toshiba: * Add support for Toshiba memory BENAND * Pass a single nand_chip object to the status helper. - ESMT: * New driver to retrieve the ECC requirements from the 5th ID byte.
This commit is contained in:
@@ -199,47 +199,57 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
|
||||
|
||||
#define __declare_arg_0(a0, res) \
|
||||
struct arm_smccc_res *___res = res; \
|
||||
register u32 r0 asm("r0") = a0; \
|
||||
register unsigned long r0 asm("r0") = (u32)a0; \
|
||||
register unsigned long r1 asm("r1"); \
|
||||
register unsigned long r2 asm("r2"); \
|
||||
register unsigned long r3 asm("r3")
|
||||
|
||||
#define __declare_arg_1(a0, a1, res) \
|
||||
typeof(a1) __a1 = a1; \
|
||||
struct arm_smccc_res *___res = res; \
|
||||
register u32 r0 asm("r0") = a0; \
|
||||
register typeof(a1) r1 asm("r1") = a1; \
|
||||
register unsigned long r0 asm("r0") = (u32)a0; \
|
||||
register unsigned long r1 asm("r1") = __a1; \
|
||||
register unsigned long r2 asm("r2"); \
|
||||
register unsigned long r3 asm("r3")
|
||||
|
||||
#define __declare_arg_2(a0, a1, a2, res) \
|
||||
typeof(a1) __a1 = a1; \
|
||||
typeof(a2) __a2 = a2; \
|
||||
struct arm_smccc_res *___res = res; \
|
||||
register u32 r0 asm("r0") = a0; \
|
||||
register typeof(a1) r1 asm("r1") = a1; \
|
||||
register typeof(a2) r2 asm("r2") = a2; \
|
||||
register unsigned long r0 asm("r0") = (u32)a0; \
|
||||
register unsigned long r1 asm("r1") = __a1; \
|
||||
register unsigned long r2 asm("r2") = __a2; \
|
||||
register unsigned long r3 asm("r3")
|
||||
|
||||
#define __declare_arg_3(a0, a1, a2, a3, res) \
|
||||
typeof(a1) __a1 = a1; \
|
||||
typeof(a2) __a2 = a2; \
|
||||
typeof(a3) __a3 = a3; \
|
||||
struct arm_smccc_res *___res = res; \
|
||||
register u32 r0 asm("r0") = a0; \
|
||||
register typeof(a1) r1 asm("r1") = a1; \
|
||||
register typeof(a2) r2 asm("r2") = a2; \
|
||||
register typeof(a3) r3 asm("r3") = a3
|
||||
register unsigned long r0 asm("r0") = (u32)a0; \
|
||||
register unsigned long r1 asm("r1") = __a1; \
|
||||
register unsigned long r2 asm("r2") = __a2; \
|
||||
register unsigned long r3 asm("r3") = __a3
|
||||
|
||||
#define __declare_arg_4(a0, a1, a2, a3, a4, res) \
|
||||
typeof(a4) __a4 = a4; \
|
||||
__declare_arg_3(a0, a1, a2, a3, res); \
|
||||
register typeof(a4) r4 asm("r4") = a4
|
||||
register unsigned long r4 asm("r4") = __a4
|
||||
|
||||
#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res) \
|
||||
typeof(a5) __a5 = a5; \
|
||||
__declare_arg_4(a0, a1, a2, a3, a4, res); \
|
||||
register typeof(a5) r5 asm("r5") = a5
|
||||
register unsigned long r5 asm("r5") = __a5
|
||||
|
||||
#define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res) \
|
||||
typeof(a6) __a6 = a6; \
|
||||
__declare_arg_5(a0, a1, a2, a3, a4, a5, res); \
|
||||
register typeof(a6) r6 asm("r6") = a6
|
||||
register unsigned long r6 asm("r6") = __a6
|
||||
|
||||
#define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res) \
|
||||
typeof(a7) __a7 = a7; \
|
||||
__declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res); \
|
||||
register typeof(a7) r7 asm("r7") = a7
|
||||
register unsigned long r7 asm("r7") = __a7
|
||||
|
||||
#define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
|
||||
#define __declare_args(count, ...) ___declare_args(count, __VA_ARGS__)
|
||||
|
@@ -274,6 +274,8 @@
|
||||
*/
|
||||
/* Auto Boot Mode */
|
||||
#define IFC_NAND_NCFGR_BOOT 0x80000000
|
||||
/* SRAM Initialization */
|
||||
#define IFC_NAND_NCFGR_SRAM_INIT_EN 0x20000000
|
||||
/* Addressing Mode-ROW0+n/COL0 */
|
||||
#define IFC_NAND_NCFGR_ADDR_MODE_RC0 0x00000000
|
||||
/* Addressing Mode-ROW0+n/COL0+n */
|
||||
|
@@ -855,7 +855,7 @@ static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
|
||||
}
|
||||
|
||||
u8 *i2c_get_dma_safe_msg_buf(struct i2c_msg *msg, unsigned int threshold);
|
||||
void i2c_release_dma_safe_msg_buf(struct i2c_msg *msg, u8 *buf);
|
||||
void i2c_put_dma_safe_msg_buf(u8 *buf, struct i2c_msg *msg, bool xferred);
|
||||
|
||||
int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr);
|
||||
/**
|
||||
|
91
include/linux/mtd/jedec.h
Normal file
91
include/linux/mtd/jedec.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
* Steven J. Hill <sjhill@realitydiluted.com>
|
||||
* Thomas Gleixner <tglx@linutronix.de>
|
||||
*
|
||||
* Contains all JEDEC related definitions
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MTD_JEDEC_H
|
||||
#define __LINUX_MTD_JEDEC_H
|
||||
|
||||
struct jedec_ecc_info {
|
||||
u8 ecc_bits;
|
||||
u8 codeword_size;
|
||||
__le16 bb_per_lun;
|
||||
__le16 block_endurance;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* JEDEC features */
|
||||
#define JEDEC_FEATURE_16_BIT_BUS (1 << 0)
|
||||
|
||||
struct nand_jedec_params {
|
||||
/* rev info and features block */
|
||||
/* 'J' 'E' 'S' 'D' */
|
||||
u8 sig[4];
|
||||
__le16 revision;
|
||||
__le16 features;
|
||||
u8 opt_cmd[3];
|
||||
__le16 sec_cmd;
|
||||
u8 num_of_param_pages;
|
||||
u8 reserved0[18];
|
||||
|
||||
/* manufacturer information block */
|
||||
char manufacturer[12];
|
||||
char model[20];
|
||||
u8 jedec_id[6];
|
||||
u8 reserved1[10];
|
||||
|
||||
/* memory organization block */
|
||||
__le32 byte_per_page;
|
||||
__le16 spare_bytes_per_page;
|
||||
u8 reserved2[6];
|
||||
__le32 pages_per_block;
|
||||
__le32 blocks_per_lun;
|
||||
u8 lun_count;
|
||||
u8 addr_cycles;
|
||||
u8 bits_per_cell;
|
||||
u8 programs_per_page;
|
||||
u8 multi_plane_addr;
|
||||
u8 multi_plane_op_attr;
|
||||
u8 reserved3[38];
|
||||
|
||||
/* electrical parameter block */
|
||||
__le16 async_sdr_speed_grade;
|
||||
__le16 toggle_ddr_speed_grade;
|
||||
__le16 sync_ddr_speed_grade;
|
||||
u8 async_sdr_features;
|
||||
u8 toggle_ddr_features;
|
||||
u8 sync_ddr_features;
|
||||
__le16 t_prog;
|
||||
__le16 t_bers;
|
||||
__le16 t_r;
|
||||
__le16 t_r_multi_plane;
|
||||
__le16 t_ccs;
|
||||
__le16 io_pin_capacitance_typ;
|
||||
__le16 input_pin_capacitance_typ;
|
||||
__le16 clk_pin_capacitance_typ;
|
||||
u8 driver_strength_support;
|
||||
__le16 t_adl;
|
||||
u8 reserved4[36];
|
||||
|
||||
/* ECC and endurance block */
|
||||
u8 guaranteed_good_blocks;
|
||||
__le16 guaranteed_block_endurance;
|
||||
struct jedec_ecc_info ecc_info[4];
|
||||
u8 reserved5[29];
|
||||
|
||||
/* reserved */
|
||||
u8 reserved6[148];
|
||||
|
||||
/* vendor */
|
||||
__le16 vendor_rev_num;
|
||||
u8 reserved7[88];
|
||||
|
||||
/* CRC for Parameter Page */
|
||||
__le16 crc;
|
||||
} __packed;
|
||||
|
||||
#endif /* __LINUX_MTD_JEDEC_H */
|
@@ -12,6 +12,7 @@
|
||||
#define __MTD_NAND_BCH_H__
|
||||
|
||||
struct mtd_info;
|
||||
struct nand_chip;
|
||||
struct nand_bch_control;
|
||||
|
||||
#if defined(CONFIG_MTD_NAND_ECC_BCH)
|
||||
@@ -21,14 +22,14 @@ static inline int mtd_nand_has_bch(void) { return 1; }
|
||||
/*
|
||||
* Calculate BCH ecc code
|
||||
*/
|
||||
int nand_bch_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
|
||||
int nand_bch_calculate_ecc(struct nand_chip *chip, const u_char *dat,
|
||||
u_char *ecc_code);
|
||||
|
||||
/*
|
||||
* Detect and correct bit errors
|
||||
*/
|
||||
int nand_bch_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc,
|
||||
u_char *calc_ecc);
|
||||
int nand_bch_correct_data(struct nand_chip *chip, u_char *dat,
|
||||
u_char *read_ecc, u_char *calc_ecc);
|
||||
/*
|
||||
* Initialize BCH encoder/decoder
|
||||
*/
|
||||
@@ -43,14 +44,14 @@ void nand_bch_free(struct nand_bch_control *nbc);
|
||||
static inline int mtd_nand_has_bch(void) { return 0; }
|
||||
|
||||
static inline int
|
||||
nand_bch_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
|
||||
nand_bch_calculate_ecc(struct nand_chip *chip, const u_char *dat,
|
||||
u_char *ecc_code)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf,
|
||||
nand_bch_correct_data(struct nand_chip *chip, unsigned char *buf,
|
||||
unsigned char *read_ecc, unsigned char *calc_ecc)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
|
@@ -13,28 +13,30 @@
|
||||
#ifndef __MTD_NAND_ECC_H__
|
||||
#define __MTD_NAND_ECC_H__
|
||||
|
||||
struct mtd_info;
|
||||
struct nand_chip;
|
||||
|
||||
/*
|
||||
* Calculate 3 byte ECC code for eccsize byte block
|
||||
*/
|
||||
void __nand_calculate_ecc(const u_char *dat, unsigned int eccsize,
|
||||
u_char *ecc_code);
|
||||
u_char *ecc_code, bool sm_order);
|
||||
|
||||
/*
|
||||
* Calculate 3 byte ECC code for 256/512 byte block
|
||||
*/
|
||||
int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
|
||||
int nand_calculate_ecc(struct nand_chip *chip, const u_char *dat,
|
||||
u_char *ecc_code);
|
||||
|
||||
/*
|
||||
* Detect and correct a 1 bit error for eccsize byte block
|
||||
*/
|
||||
int __nand_correct_data(u_char *dat, u_char *read_ecc, u_char *calc_ecc,
|
||||
unsigned int eccsize);
|
||||
unsigned int eccsize, bool sm_order);
|
||||
|
||||
/*
|
||||
* Detect and correct a 1 bit error for 256/512 byte block
|
||||
*/
|
||||
int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
|
||||
int nand_correct_data(struct nand_chip *chip, u_char *dat, u_char *read_ecc,
|
||||
u_char *calc_ecc);
|
||||
|
||||
#endif /* __MTD_NAND_ECC_H__ */
|
||||
|
178
include/linux/mtd/onfi.h
Normal file
178
include/linux/mtd/onfi.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
* Steven J. Hill <sjhill@realitydiluted.com>
|
||||
* Thomas Gleixner <tglx@linutronix.de>
|
||||
*
|
||||
* Contains all ONFI related definitions
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MTD_ONFI_H
|
||||
#define __LINUX_MTD_ONFI_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* ONFI version bits */
|
||||
#define ONFI_VERSION_1_0 BIT(1)
|
||||
#define ONFI_VERSION_2_0 BIT(2)
|
||||
#define ONFI_VERSION_2_1 BIT(3)
|
||||
#define ONFI_VERSION_2_2 BIT(4)
|
||||
#define ONFI_VERSION_2_3 BIT(5)
|
||||
#define ONFI_VERSION_3_0 BIT(6)
|
||||
#define ONFI_VERSION_3_1 BIT(7)
|
||||
#define ONFI_VERSION_3_2 BIT(8)
|
||||
#define ONFI_VERSION_4_0 BIT(9)
|
||||
|
||||
/* ONFI features */
|
||||
#define ONFI_FEATURE_16_BIT_BUS (1 << 0)
|
||||
#define ONFI_FEATURE_EXT_PARAM_PAGE (1 << 7)
|
||||
|
||||
/* ONFI timing mode, used in both asynchronous and synchronous mode */
|
||||
#define ONFI_TIMING_MODE_0 (1 << 0)
|
||||
#define ONFI_TIMING_MODE_1 (1 << 1)
|
||||
#define ONFI_TIMING_MODE_2 (1 << 2)
|
||||
#define ONFI_TIMING_MODE_3 (1 << 3)
|
||||
#define ONFI_TIMING_MODE_4 (1 << 4)
|
||||
#define ONFI_TIMING_MODE_5 (1 << 5)
|
||||
#define ONFI_TIMING_MODE_UNKNOWN (1 << 6)
|
||||
|
||||
/* ONFI feature number/address */
|
||||
#define ONFI_FEATURE_NUMBER 256
|
||||
#define ONFI_FEATURE_ADDR_TIMING_MODE 0x1
|
||||
|
||||
/* Vendor-specific feature address (Micron) */
|
||||
#define ONFI_FEATURE_ADDR_READ_RETRY 0x89
|
||||
#define ONFI_FEATURE_ON_DIE_ECC 0x90
|
||||
#define ONFI_FEATURE_ON_DIE_ECC_EN BIT(3)
|
||||
|
||||
/* ONFI subfeature parameters length */
|
||||
#define ONFI_SUBFEATURE_PARAM_LEN 4
|
||||
|
||||
/* ONFI optional commands SET/GET FEATURES supported? */
|
||||
#define ONFI_OPT_CMD_SET_GET_FEATURES (1 << 2)
|
||||
|
||||
struct nand_onfi_params {
|
||||
/* rev info and features block */
|
||||
/* 'O' 'N' 'F' 'I' */
|
||||
u8 sig[4];
|
||||
__le16 revision;
|
||||
__le16 features;
|
||||
__le16 opt_cmd;
|
||||
u8 reserved0[2];
|
||||
__le16 ext_param_page_length; /* since ONFI 2.1 */
|
||||
u8 num_of_param_pages; /* since ONFI 2.1 */
|
||||
u8 reserved1[17];
|
||||
|
||||
/* manufacturer information block */
|
||||
char manufacturer[12];
|
||||
char model[20];
|
||||
u8 jedec_id;
|
||||
__le16 date_code;
|
||||
u8 reserved2[13];
|
||||
|
||||
/* memory organization block */
|
||||
__le32 byte_per_page;
|
||||
__le16 spare_bytes_per_page;
|
||||
__le32 data_bytes_per_ppage;
|
||||
__le16 spare_bytes_per_ppage;
|
||||
__le32 pages_per_block;
|
||||
__le32 blocks_per_lun;
|
||||
u8 lun_count;
|
||||
u8 addr_cycles;
|
||||
u8 bits_per_cell;
|
||||
__le16 bb_per_lun;
|
||||
__le16 block_endurance;
|
||||
u8 guaranteed_good_blocks;
|
||||
__le16 guaranteed_block_endurance;
|
||||
u8 programs_per_page;
|
||||
u8 ppage_attr;
|
||||
u8 ecc_bits;
|
||||
u8 interleaved_bits;
|
||||
u8 interleaved_ops;
|
||||
u8 reserved3[13];
|
||||
|
||||
/* electrical parameter block */
|
||||
u8 io_pin_capacitance_max;
|
||||
__le16 async_timing_mode;
|
||||
__le16 program_cache_timing_mode;
|
||||
__le16 t_prog;
|
||||
__le16 t_bers;
|
||||
__le16 t_r;
|
||||
__le16 t_ccs;
|
||||
__le16 src_sync_timing_mode;
|
||||
u8 src_ssync_features;
|
||||
__le16 clk_pin_capacitance_typ;
|
||||
__le16 io_pin_capacitance_typ;
|
||||
__le16 input_pin_capacitance_typ;
|
||||
u8 input_pin_capacitance_max;
|
||||
u8 driver_strength_support;
|
||||
__le16 t_int_r;
|
||||
__le16 t_adl;
|
||||
u8 reserved4[8];
|
||||
|
||||
/* vendor */
|
||||
__le16 vendor_revision;
|
||||
u8 vendor[88];
|
||||
|
||||
__le16 crc;
|
||||
} __packed;
|
||||
|
||||
#define ONFI_CRC_BASE 0x4F4E
|
||||
|
||||
/* Extended ECC information Block Definition (since ONFI 2.1) */
|
||||
struct onfi_ext_ecc_info {
|
||||
u8 ecc_bits;
|
||||
u8 codeword_size;
|
||||
__le16 bb_per_lun;
|
||||
__le16 block_endurance;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
#define ONFI_SECTION_TYPE_0 0 /* Unused section. */
|
||||
#define ONFI_SECTION_TYPE_1 1 /* for additional sections. */
|
||||
#define ONFI_SECTION_TYPE_2 2 /* for ECC information. */
|
||||
struct onfi_ext_section {
|
||||
u8 type;
|
||||
u8 length;
|
||||
} __packed;
|
||||
|
||||
#define ONFI_EXT_SECTION_MAX 8
|
||||
|
||||
/* Extended Parameter Page Definition (since ONFI 2.1) */
|
||||
struct onfi_ext_param_page {
|
||||
__le16 crc;
|
||||
u8 sig[4]; /* 'E' 'P' 'P' 'S' */
|
||||
u8 reserved0[10];
|
||||
struct onfi_ext_section sections[ONFI_EXT_SECTION_MAX];
|
||||
|
||||
/*
|
||||
* The actual size of the Extended Parameter Page is in
|
||||
* @ext_param_page_length of nand_onfi_params{}.
|
||||
* The following are the variable length sections.
|
||||
* So we do not add any fields below. Please see the ONFI spec.
|
||||
*/
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct onfi_params - ONFI specific parameters that will be reused
|
||||
* @version: ONFI version (BCD encoded), 0 if ONFI is not supported
|
||||
* @tPROG: Page program time
|
||||
* @tBERS: Block erase time
|
||||
* @tR: Page read time
|
||||
* @tCCS: Change column setup time
|
||||
* @async_timing_mode: Supported asynchronous timing mode
|
||||
* @vendor_revision: Vendor specific revision number
|
||||
* @vendor: Vendor specific data
|
||||
*/
|
||||
struct onfi_params {
|
||||
int version;
|
||||
u16 tPROG;
|
||||
u16 tBERS;
|
||||
u16 tR;
|
||||
u16 tCCS;
|
||||
u16 async_timing_mode;
|
||||
u16 vendor_revision;
|
||||
u8 vendor[88];
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MTD_ONFI_H */
|
74
include/linux/mtd/platnand.h
Normal file
74
include/linux/mtd/platnand.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
* Steven J. Hill <sjhill@realitydiluted.com>
|
||||
* Thomas Gleixner <tglx@linutronix.de>
|
||||
*
|
||||
* Contains all platform NAND related definitions.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MTD_PLATNAND_H
|
||||
#define __LINUX_MTD_PLATNAND_H
|
||||
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/rawnand.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
/**
|
||||
* struct platform_nand_chip - chip level device structure
|
||||
* @nr_chips: max. number of chips to scan for
|
||||
* @chip_offset: chip number offset
|
||||
* @nr_partitions: number of partitions pointed to by partitions (or zero)
|
||||
* @partitions: mtd partition list
|
||||
* @chip_delay: R/B delay value in us
|
||||
* @options: Option flags, e.g. 16bit buswidth
|
||||
* @bbt_options: BBT option flags, e.g. NAND_BBT_USE_FLASH
|
||||
* @part_probe_types: NULL-terminated array of probe types
|
||||
*/
|
||||
struct platform_nand_chip {
|
||||
int nr_chips;
|
||||
int chip_offset;
|
||||
int nr_partitions;
|
||||
struct mtd_partition *partitions;
|
||||
int chip_delay;
|
||||
unsigned int options;
|
||||
unsigned int bbt_options;
|
||||
const char **part_probe_types;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct platform_nand_ctrl - controller level device structure
|
||||
* @probe: platform specific function to probe/setup hardware
|
||||
* @remove: platform specific function to remove/teardown hardware
|
||||
* @dev_ready: platform specific function to read ready/busy pin
|
||||
* @select_chip: platform specific chip select function
|
||||
* @cmd_ctrl: platform specific function for controlling
|
||||
* ALE/CLE/nCE. Also used to write command and address
|
||||
* @write_buf: platform specific function for write buffer
|
||||
* @read_buf: platform specific function for read buffer
|
||||
* @priv: private data to transport driver specific settings
|
||||
*
|
||||
* All fields are optional and depend on the hardware driver requirements
|
||||
*/
|
||||
struct platform_nand_ctrl {
|
||||
int (*probe)(struct platform_device *pdev);
|
||||
void (*remove)(struct platform_device *pdev);
|
||||
int (*dev_ready)(struct nand_chip *chip);
|
||||
void (*select_chip)(struct nand_chip *chip, int cs);
|
||||
void (*cmd_ctrl)(struct nand_chip *chip, int dat, unsigned int ctrl);
|
||||
void (*write_buf)(struct nand_chip *chip, const uint8_t *buf, int len);
|
||||
void (*read_buf)(struct nand_chip *chip, uint8_t *buf, int len);
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct platform_nand_data - container structure for platform-specific data
|
||||
* @chip: chip level chip structure
|
||||
* @ctrl: controller level device structure
|
||||
*/
|
||||
struct platform_nand_data {
|
||||
struct platform_nand_chip chip;
|
||||
struct platform_nand_ctrl ctrl;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MTD_PLATNAND_H */
|
@@ -21,22 +21,12 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/flashchip.h>
|
||||
#include <linux/mtd/bbm.h>
|
||||
#include <linux/mtd/jedec.h>
|
||||
#include <linux/mtd/onfi.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
struct nand_flash_dev;
|
||||
|
||||
/* Scan and identify a NAND device */
|
||||
int nand_scan_with_ids(struct mtd_info *mtd, int max_chips,
|
||||
struct nand_flash_dev *ids);
|
||||
|
||||
static inline int nand_scan(struct mtd_info *mtd, int max_chips)
|
||||
{
|
||||
return nand_scan_with_ids(mtd, max_chips, NULL);
|
||||
}
|
||||
|
||||
/* Internal helper for board drivers which need to override command function */
|
||||
void nand_wait_ready(struct mtd_info *mtd);
|
||||
struct nand_chip;
|
||||
|
||||
/* The maximum number of NAND chips in an array */
|
||||
#define NAND_MAX_CHIPS 8
|
||||
@@ -131,9 +121,11 @@ enum nand_ecc_algo {
|
||||
#define NAND_ECC_GENERIC_ERASED_CHECK BIT(0)
|
||||
#define NAND_ECC_MAXIMIZE BIT(1)
|
||||
|
||||
/* Bit mask for flags passed to do_nand_read_ecc */
|
||||
#define NAND_GET_DEVICE 0x80
|
||||
|
||||
/*
|
||||
* When using software implementation of Hamming, we can specify which byte
|
||||
* ordering should be used.
|
||||
*/
|
||||
#define NAND_ECC_SOFT_HAMMING_SM_ORDER BIT(2)
|
||||
|
||||
/*
|
||||
* Option constants for bizarre disfunctionality and real
|
||||
@@ -175,9 +167,7 @@ enum nand_ecc_algo {
|
||||
#define NAND_SAMSUNG_LP_OPTIONS NAND_CACHEPRG
|
||||
|
||||
/* Macros to identify the above */
|
||||
#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
|
||||
#define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
|
||||
#define NAND_HAS_SUBPAGE_WRITE(chip) !((chip)->options & NAND_NO_SUBPAGE_WRITE)
|
||||
|
||||
/* Non chip related options */
|
||||
/* This option skips the bbt scan during initialization. */
|
||||
@@ -198,10 +188,10 @@ enum nand_ecc_algo {
|
||||
#define NAND_USE_BOUNCE_BUFFER 0x00100000
|
||||
|
||||
/*
|
||||
* In case your controller is implementing ->cmd_ctrl() and is relying on the
|
||||
* default ->cmdfunc() implementation, you may want to let the core handle the
|
||||
* tCCS delay which is required when a column change (RNDIN or RNDOUT) is
|
||||
* requested.
|
||||
* In case your controller is implementing ->legacy.cmd_ctrl() and is relying
|
||||
* on the default ->cmdfunc() implementation, you may want to let the core
|
||||
* handle the tCCS delay which is required when a column change (RNDIN or
|
||||
* RNDOUT) is requested.
|
||||
* If your controller already takes care of this delay, you don't need to set
|
||||
* this flag.
|
||||
*/
|
||||
@@ -222,250 +212,6 @@ enum nand_ecc_algo {
|
||||
#define NAND_CI_CELLTYPE_MSK 0x0C
|
||||
#define NAND_CI_CELLTYPE_SHIFT 2
|
||||
|
||||
/* Keep gcc happy */
|
||||
struct nand_chip;
|
||||
|
||||
/* ONFI version bits */
|
||||
#define ONFI_VERSION_1_0 BIT(1)
|
||||
#define ONFI_VERSION_2_0 BIT(2)
|
||||
#define ONFI_VERSION_2_1 BIT(3)
|
||||
#define ONFI_VERSION_2_2 BIT(4)
|
||||
#define ONFI_VERSION_2_3 BIT(5)
|
||||
#define ONFI_VERSION_3_0 BIT(6)
|
||||
#define ONFI_VERSION_3_1 BIT(7)
|
||||
#define ONFI_VERSION_3_2 BIT(8)
|
||||
#define ONFI_VERSION_4_0 BIT(9)
|
||||
|
||||
/* ONFI features */
|
||||
#define ONFI_FEATURE_16_BIT_BUS (1 << 0)
|
||||
#define ONFI_FEATURE_EXT_PARAM_PAGE (1 << 7)
|
||||
|
||||
/* ONFI timing mode, used in both asynchronous and synchronous mode */
|
||||
#define ONFI_TIMING_MODE_0 (1 << 0)
|
||||
#define ONFI_TIMING_MODE_1 (1 << 1)
|
||||
#define ONFI_TIMING_MODE_2 (1 << 2)
|
||||
#define ONFI_TIMING_MODE_3 (1 << 3)
|
||||
#define ONFI_TIMING_MODE_4 (1 << 4)
|
||||
#define ONFI_TIMING_MODE_5 (1 << 5)
|
||||
#define ONFI_TIMING_MODE_UNKNOWN (1 << 6)
|
||||
|
||||
/* ONFI feature number/address */
|
||||
#define ONFI_FEATURE_NUMBER 256
|
||||
#define ONFI_FEATURE_ADDR_TIMING_MODE 0x1
|
||||
|
||||
/* Vendor-specific feature address (Micron) */
|
||||
#define ONFI_FEATURE_ADDR_READ_RETRY 0x89
|
||||
#define ONFI_FEATURE_ON_DIE_ECC 0x90
|
||||
#define ONFI_FEATURE_ON_DIE_ECC_EN BIT(3)
|
||||
|
||||
/* ONFI subfeature parameters length */
|
||||
#define ONFI_SUBFEATURE_PARAM_LEN 4
|
||||
|
||||
/* ONFI optional commands SET/GET FEATURES supported? */
|
||||
#define ONFI_OPT_CMD_SET_GET_FEATURES (1 << 2)
|
||||
|
||||
struct nand_onfi_params {
|
||||
/* rev info and features block */
|
||||
/* 'O' 'N' 'F' 'I' */
|
||||
u8 sig[4];
|
||||
__le16 revision;
|
||||
__le16 features;
|
||||
__le16 opt_cmd;
|
||||
u8 reserved0[2];
|
||||
__le16 ext_param_page_length; /* since ONFI 2.1 */
|
||||
u8 num_of_param_pages; /* since ONFI 2.1 */
|
||||
u8 reserved1[17];
|
||||
|
||||
/* manufacturer information block */
|
||||
char manufacturer[12];
|
||||
char model[20];
|
||||
u8 jedec_id;
|
||||
__le16 date_code;
|
||||
u8 reserved2[13];
|
||||
|
||||
/* memory organization block */
|
||||
__le32 byte_per_page;
|
||||
__le16 spare_bytes_per_page;
|
||||
__le32 data_bytes_per_ppage;
|
||||
__le16 spare_bytes_per_ppage;
|
||||
__le32 pages_per_block;
|
||||
__le32 blocks_per_lun;
|
||||
u8 lun_count;
|
||||
u8 addr_cycles;
|
||||
u8 bits_per_cell;
|
||||
__le16 bb_per_lun;
|
||||
__le16 block_endurance;
|
||||
u8 guaranteed_good_blocks;
|
||||
__le16 guaranteed_block_endurance;
|
||||
u8 programs_per_page;
|
||||
u8 ppage_attr;
|
||||
u8 ecc_bits;
|
||||
u8 interleaved_bits;
|
||||
u8 interleaved_ops;
|
||||
u8 reserved3[13];
|
||||
|
||||
/* electrical parameter block */
|
||||
u8 io_pin_capacitance_max;
|
||||
__le16 async_timing_mode;
|
||||
__le16 program_cache_timing_mode;
|
||||
__le16 t_prog;
|
||||
__le16 t_bers;
|
||||
__le16 t_r;
|
||||
__le16 t_ccs;
|
||||
__le16 src_sync_timing_mode;
|
||||
u8 src_ssync_features;
|
||||
__le16 clk_pin_capacitance_typ;
|
||||
__le16 io_pin_capacitance_typ;
|
||||
__le16 input_pin_capacitance_typ;
|
||||
u8 input_pin_capacitance_max;
|
||||
u8 driver_strength_support;
|
||||
__le16 t_int_r;
|
||||
__le16 t_adl;
|
||||
u8 reserved4[8];
|
||||
|
||||
/* vendor */
|
||||
__le16 vendor_revision;
|
||||
u8 vendor[88];
|
||||
|
||||
__le16 crc;
|
||||
} __packed;
|
||||
|
||||
#define ONFI_CRC_BASE 0x4F4E
|
||||
|
||||
/* Extended ECC information Block Definition (since ONFI 2.1) */
|
||||
struct onfi_ext_ecc_info {
|
||||
u8 ecc_bits;
|
||||
u8 codeword_size;
|
||||
__le16 bb_per_lun;
|
||||
__le16 block_endurance;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
#define ONFI_SECTION_TYPE_0 0 /* Unused section. */
|
||||
#define ONFI_SECTION_TYPE_1 1 /* for additional sections. */
|
||||
#define ONFI_SECTION_TYPE_2 2 /* for ECC information. */
|
||||
struct onfi_ext_section {
|
||||
u8 type;
|
||||
u8 length;
|
||||
} __packed;
|
||||
|
||||
#define ONFI_EXT_SECTION_MAX 8
|
||||
|
||||
/* Extended Parameter Page Definition (since ONFI 2.1) */
|
||||
struct onfi_ext_param_page {
|
||||
__le16 crc;
|
||||
u8 sig[4]; /* 'E' 'P' 'P' 'S' */
|
||||
u8 reserved0[10];
|
||||
struct onfi_ext_section sections[ONFI_EXT_SECTION_MAX];
|
||||
|
||||
/*
|
||||
* The actual size of the Extended Parameter Page is in
|
||||
* @ext_param_page_length of nand_onfi_params{}.
|
||||
* The following are the variable length sections.
|
||||
* So we do not add any fields below. Please see the ONFI spec.
|
||||
*/
|
||||
} __packed;
|
||||
|
||||
struct jedec_ecc_info {
|
||||
u8 ecc_bits;
|
||||
u8 codeword_size;
|
||||
__le16 bb_per_lun;
|
||||
__le16 block_endurance;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* JEDEC features */
|
||||
#define JEDEC_FEATURE_16_BIT_BUS (1 << 0)
|
||||
|
||||
struct nand_jedec_params {
|
||||
/* rev info and features block */
|
||||
/* 'J' 'E' 'S' 'D' */
|
||||
u8 sig[4];
|
||||
__le16 revision;
|
||||
__le16 features;
|
||||
u8 opt_cmd[3];
|
||||
__le16 sec_cmd;
|
||||
u8 num_of_param_pages;
|
||||
u8 reserved0[18];
|
||||
|
||||
/* manufacturer information block */
|
||||
char manufacturer[12];
|
||||
char model[20];
|
||||
u8 jedec_id[6];
|
||||
u8 reserved1[10];
|
||||
|
||||
/* memory organization block */
|
||||
__le32 byte_per_page;
|
||||
__le16 spare_bytes_per_page;
|
||||
u8 reserved2[6];
|
||||
__le32 pages_per_block;
|
||||
__le32 blocks_per_lun;
|
||||
u8 lun_count;
|
||||
u8 addr_cycles;
|
||||
u8 bits_per_cell;
|
||||
u8 programs_per_page;
|
||||
u8 multi_plane_addr;
|
||||
u8 multi_plane_op_attr;
|
||||
u8 reserved3[38];
|
||||
|
||||
/* electrical parameter block */
|
||||
__le16 async_sdr_speed_grade;
|
||||
__le16 toggle_ddr_speed_grade;
|
||||
__le16 sync_ddr_speed_grade;
|
||||
u8 async_sdr_features;
|
||||
u8 toggle_ddr_features;
|
||||
u8 sync_ddr_features;
|
||||
__le16 t_prog;
|
||||
__le16 t_bers;
|
||||
__le16 t_r;
|
||||
__le16 t_r_multi_plane;
|
||||
__le16 t_ccs;
|
||||
__le16 io_pin_capacitance_typ;
|
||||
__le16 input_pin_capacitance_typ;
|
||||
__le16 clk_pin_capacitance_typ;
|
||||
u8 driver_strength_support;
|
||||
__le16 t_adl;
|
||||
u8 reserved4[36];
|
||||
|
||||
/* ECC and endurance block */
|
||||
u8 guaranteed_good_blocks;
|
||||
__le16 guaranteed_block_endurance;
|
||||
struct jedec_ecc_info ecc_info[4];
|
||||
u8 reserved5[29];
|
||||
|
||||
/* reserved */
|
||||
u8 reserved6[148];
|
||||
|
||||
/* vendor */
|
||||
__le16 vendor_rev_num;
|
||||
u8 reserved7[88];
|
||||
|
||||
/* CRC for Parameter Page */
|
||||
__le16 crc;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct onfi_params - ONFI specific parameters that will be reused
|
||||
* @version: ONFI version (BCD encoded), 0 if ONFI is not supported
|
||||
* @tPROG: Page program time
|
||||
* @tBERS: Block erase time
|
||||
* @tR: Page read time
|
||||
* @tCCS: Change column setup time
|
||||
* @async_timing_mode: Supported asynchronous timing mode
|
||||
* @vendor_revision: Vendor specific revision number
|
||||
* @vendor: Vendor specific data
|
||||
*/
|
||||
struct onfi_params {
|
||||
int version;
|
||||
u16 tPROG;
|
||||
u16 tBERS;
|
||||
u16 tR;
|
||||
u16 tCCS;
|
||||
u16 async_timing_mode;
|
||||
u16 vendor_revision;
|
||||
u8 vendor[88];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nand_parameters - NAND generic parameters from the parameter page
|
||||
* @model: Model name
|
||||
@@ -646,31 +392,28 @@ struct nand_ecc_ctrl {
|
||||
void *priv;
|
||||
u8 *calc_buf;
|
||||
u8 *code_buf;
|
||||
void (*hwctl)(struct mtd_info *mtd, int mode);
|
||||
int (*calculate)(struct mtd_info *mtd, const uint8_t *dat,
|
||||
uint8_t *ecc_code);
|
||||
int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc,
|
||||
uint8_t *calc_ecc);
|
||||
int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
uint8_t *buf, int oob_required, int page);
|
||||
int (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
const uint8_t *buf, int oob_required, int page);
|
||||
int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
uint8_t *buf, int oob_required, int page);
|
||||
int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
uint32_t offs, uint32_t len, uint8_t *buf, int page);
|
||||
int (*write_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
uint32_t offset, uint32_t data_len,
|
||||
const uint8_t *data_buf, int oob_required, int page);
|
||||
int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
const uint8_t *buf, int oob_required, int page);
|
||||
int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
int page);
|
||||
int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
int page);
|
||||
int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page);
|
||||
int (*write_oob)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
int page);
|
||||
void (*hwctl)(struct nand_chip *chip, int mode);
|
||||
int (*calculate)(struct nand_chip *chip, const uint8_t *dat,
|
||||
uint8_t *ecc_code);
|
||||
int (*correct)(struct nand_chip *chip, uint8_t *dat, uint8_t *read_ecc,
|
||||
uint8_t *calc_ecc);
|
||||
int (*read_page_raw)(struct nand_chip *chip, uint8_t *buf,
|
||||
int oob_required, int page);
|
||||
int (*write_page_raw)(struct nand_chip *chip, const uint8_t *buf,
|
||||
int oob_required, int page);
|
||||
int (*read_page)(struct nand_chip *chip, uint8_t *buf,
|
||||
int oob_required, int page);
|
||||
int (*read_subpage)(struct nand_chip *chip, uint32_t offs,
|
||||
uint32_t len, uint8_t *buf, int page);
|
||||
int (*write_subpage)(struct nand_chip *chip, uint32_t offset,
|
||||
uint32_t data_len, const uint8_t *data_buf,
|
||||
int oob_required, int page);
|
||||
int (*write_page)(struct nand_chip *chip, const uint8_t *buf,
|
||||
int oob_required, int page);
|
||||
int (*write_oob_raw)(struct nand_chip *chip, int page);
|
||||
int (*read_oob_raw)(struct nand_chip *chip, int page);
|
||||
int (*read_oob)(struct nand_chip *chip, int page);
|
||||
int (*write_oob)(struct nand_chip *chip, int page);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -799,24 +542,6 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
|
||||
return &conf->timings.sdr;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct nand_manufacturer_ops - NAND Manufacturer operations
|
||||
* @detect: detect the NAND memory organization and capabilities
|
||||
* @init: initialize all vendor specific fields (like the ->read_retry()
|
||||
* implementation) if any.
|
||||
* @cleanup: the ->init() function may have allocated resources, ->cleanup()
|
||||
* is here to let vendor specific code release those resources.
|
||||
* @fixup_onfi_param_page: apply vendor specific fixups to the ONFI parameter
|
||||
* page. This is called after the checksum is verified.
|
||||
*/
|
||||
struct nand_manufacturer_ops {
|
||||
void (*detect)(struct nand_chip *chip);
|
||||
int (*init)(struct nand_chip *chip);
|
||||
void (*cleanup)(struct nand_chip *chip);
|
||||
void (*fixup_onfi_param_page)(struct nand_chip *chip,
|
||||
struct nand_onfi_params *p);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nand_op_cmd_instr - Definition of a command instruction
|
||||
* @opcode: the command to issue in one cycle
|
||||
@@ -1174,45 +899,73 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
|
||||
const struct nand_op_parser *parser,
|
||||
const struct nand_operation *op, bool check_only);
|
||||
|
||||
/**
|
||||
* struct nand_legacy - NAND chip legacy fields/hooks
|
||||
* @IO_ADDR_R: address to read the 8 I/O lines of the flash device
|
||||
* @IO_ADDR_W: address to write the 8 I/O lines of the flash device
|
||||
* @read_byte: read one byte from the chip
|
||||
* @write_byte: write a single byte to the chip on the low 8 I/O lines
|
||||
* @write_buf: write data from the buffer to the chip
|
||||
* @read_buf: read data from the chip into the buffer
|
||||
* @cmd_ctrl: hardware specific function for controlling ALE/CLE/nCE. Also used
|
||||
* to write command and address
|
||||
* @cmdfunc: hardware specific function for writing commands to the chip.
|
||||
* @dev_ready: hardware specific function for accessing device ready/busy line.
|
||||
* If set to NULL no access to ready/busy is available and the
|
||||
* ready/busy information is read from the chip status register.
|
||||
* @waitfunc: hardware specific function for wait on ready.
|
||||
* @block_bad: check if a block is bad, using OOB markers
|
||||
* @block_markbad: mark a block bad
|
||||
* @erase: erase function
|
||||
* @set_features: set the NAND chip features
|
||||
* @get_features: get the NAND chip features
|
||||
* @chip_delay: chip dependent delay for transferring data from array to read
|
||||
* regs (tR).
|
||||
*
|
||||
* If you look at this structure you're already wrong. These fields/hooks are
|
||||
* all deprecated.
|
||||
*/
|
||||
struct nand_legacy {
|
||||
void __iomem *IO_ADDR_R;
|
||||
void __iomem *IO_ADDR_W;
|
||||
u8 (*read_byte)(struct nand_chip *chip);
|
||||
void (*write_byte)(struct nand_chip *chip, u8 byte);
|
||||
void (*write_buf)(struct nand_chip *chip, const u8 *buf, int len);
|
||||
void (*read_buf)(struct nand_chip *chip, u8 *buf, int len);
|
||||
void (*cmd_ctrl)(struct nand_chip *chip, int dat, unsigned int ctrl);
|
||||
void (*cmdfunc)(struct nand_chip *chip, unsigned command, int column,
|
||||
int page_addr);
|
||||
int (*dev_ready)(struct nand_chip *chip);
|
||||
int (*waitfunc)(struct nand_chip *chip);
|
||||
int (*block_bad)(struct nand_chip *chip, loff_t ofs);
|
||||
int (*block_markbad)(struct nand_chip *chip, loff_t ofs);
|
||||
int (*erase)(struct nand_chip *chip, int page);
|
||||
int (*set_features)(struct nand_chip *chip, int feature_addr,
|
||||
u8 *subfeature_para);
|
||||
int (*get_features)(struct nand_chip *chip, int feature_addr,
|
||||
u8 *subfeature_para);
|
||||
int chip_delay;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nand_chip - NAND Private Flash Chip Data
|
||||
* @mtd: MTD device registered to the MTD framework
|
||||
* @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the
|
||||
* flash device
|
||||
* @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the
|
||||
* flash device.
|
||||
* @read_byte: [REPLACEABLE] read one byte from the chip
|
||||
* @read_word: [REPLACEABLE] read one word from the chip
|
||||
* @write_byte: [REPLACEABLE] write a single byte to the chip on the
|
||||
* low 8 I/O lines
|
||||
* @write_buf: [REPLACEABLE] write data from the buffer to the chip
|
||||
* @read_buf: [REPLACEABLE] read data from the chip into the buffer
|
||||
* @legacy: All legacy fields/hooks. If you develop a new driver,
|
||||
* don't even try to use any of these fields/hooks, and if
|
||||
* you're modifying an existing driver that is using those
|
||||
* fields/hooks, you should consider reworking the driver
|
||||
* avoid using them.
|
||||
* @select_chip: [REPLACEABLE] select chip nr
|
||||
* @block_bad: [REPLACEABLE] check if a block is bad, using OOB markers
|
||||
* @block_markbad: [REPLACEABLE] mark a block bad
|
||||
* @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific function for controlling
|
||||
* ALE/CLE/nCE. Also used to write command and address
|
||||
* @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accessing
|
||||
* device ready/busy line. If set to NULL no access to
|
||||
* ready/busy is available and the ready/busy information
|
||||
* is read from the chip status register.
|
||||
* @cmdfunc: [REPLACEABLE] hardwarespecific function for writing
|
||||
* commands to the chip.
|
||||
* @waitfunc: [REPLACEABLE] hardwarespecific function for wait on
|
||||
* ready.
|
||||
* @exec_op: controller specific method to execute NAND operations.
|
||||
* This method replaces ->cmdfunc(),
|
||||
* ->{read,write}_{buf,byte,word}(), ->dev_ready() and
|
||||
* ->waifunc().
|
||||
* ->legacy.{read,write}_{buf,byte,word}(),
|
||||
* ->legacy.dev_ready() and ->waifunc().
|
||||
* @setup_read_retry: [FLASHSPECIFIC] flash (vendor) specific function for
|
||||
* setting the read-retry mode. Mostly needed for MLC NAND.
|
||||
* @ecc: [BOARDSPECIFIC] ECC control structure
|
||||
* @buf_align: minimum buffer alignment required by a platform
|
||||
* @dummy_controller: dummy controller implementation for drivers that can
|
||||
* only control a single chip
|
||||
* @erase: [REPLACEABLE] erase function
|
||||
* @chip_delay: [BOARDSPECIFIC] chip dependent delay for transferring
|
||||
* data from array to read regs (tR).
|
||||
* @state: [INTERN] the current state of the NAND device
|
||||
* @oob_poi: "poison value buffer," used for laying out OOB data
|
||||
* before writing
|
||||
@@ -1260,8 +1013,6 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
|
||||
* @blocks_per_die: [INTERN] The number of PEBs in a die
|
||||
* @data_interface: [INTERN] NAND interface timing information
|
||||
* @read_retries: [INTERN] the number of read retry modes supported
|
||||
* @set_features: [REPLACEABLE] set the NAND chip features
|
||||
* @get_features: [REPLACEABLE] get the NAND chip features
|
||||
* @setup_data_interface: [OPTIONAL] setup the data interface and timing. If
|
||||
* chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this
|
||||
* means the configuration should not be applied but
|
||||
@@ -1283,35 +1034,17 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
|
||||
|
||||
struct nand_chip {
|
||||
struct mtd_info mtd;
|
||||
void __iomem *IO_ADDR_R;
|
||||
void __iomem *IO_ADDR_W;
|
||||
|
||||
uint8_t (*read_byte)(struct mtd_info *mtd);
|
||||
u16 (*read_word)(struct mtd_info *mtd);
|
||||
void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
|
||||
void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
|
||||
void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
|
||||
void (*select_chip)(struct mtd_info *mtd, int chip);
|
||||
int (*block_bad)(struct mtd_info *mtd, loff_t ofs);
|
||||
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
|
||||
void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
|
||||
int (*dev_ready)(struct mtd_info *mtd);
|
||||
void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column,
|
||||
int page_addr);
|
||||
int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
|
||||
struct nand_legacy legacy;
|
||||
|
||||
void (*select_chip)(struct nand_chip *chip, int cs);
|
||||
int (*exec_op)(struct nand_chip *chip,
|
||||
const struct nand_operation *op,
|
||||
bool check_only);
|
||||
int (*erase)(struct mtd_info *mtd, int page);
|
||||
int (*set_features)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
int feature_addr, uint8_t *subfeature_para);
|
||||
int (*get_features)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
int feature_addr, uint8_t *subfeature_para);
|
||||
int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode);
|
||||
int (*setup_data_interface)(struct mtd_info *mtd, int chipnr,
|
||||
int (*setup_read_retry)(struct nand_chip *chip, int retry_mode);
|
||||
int (*setup_data_interface)(struct nand_chip *chip, int chipnr,
|
||||
const struct nand_data_interface *conf);
|
||||
|
||||
int chip_delay;
|
||||
unsigned int options;
|
||||
unsigned int bbt_options;
|
||||
|
||||
@@ -1419,27 +1152,6 @@ static inline void *nand_get_manufacturer_data(struct nand_chip *chip)
|
||||
return chip->manufacturer.priv;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAND Flash Manufacturer ID Codes
|
||||
*/
|
||||
#define NAND_MFR_TOSHIBA 0x98
|
||||
#define NAND_MFR_ESMT 0xc8
|
||||
#define NAND_MFR_SAMSUNG 0xec
|
||||
#define NAND_MFR_FUJITSU 0x04
|
||||
#define NAND_MFR_NATIONAL 0x8f
|
||||
#define NAND_MFR_RENESAS 0x07
|
||||
#define NAND_MFR_STMICRO 0x20
|
||||
#define NAND_MFR_HYNIX 0xad
|
||||
#define NAND_MFR_MICRON 0x2c
|
||||
#define NAND_MFR_AMD 0x01
|
||||
#define NAND_MFR_MACRONIX 0xc2
|
||||
#define NAND_MFR_EON 0x92
|
||||
#define NAND_MFR_SANDISK 0x45
|
||||
#define NAND_MFR_INTEL 0x89
|
||||
#define NAND_MFR_ATO 0x9b
|
||||
#define NAND_MFR_WINBOND 0xef
|
||||
|
||||
|
||||
/*
|
||||
* A helper for defining older NAND chips where the second ID byte fully
|
||||
* defined the chip, including the geometry (chip size, eraseblock size, page
|
||||
@@ -1519,114 +1231,7 @@ struct nand_flash_dev {
|
||||
int onfi_timing_mode_default;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nand_manufacturer - NAND Flash Manufacturer structure
|
||||
* @name: Manufacturer name
|
||||
* @id: manufacturer ID code of device.
|
||||
* @ops: manufacturer operations
|
||||
*/
|
||||
struct nand_manufacturer {
|
||||
int id;
|
||||
char *name;
|
||||
const struct nand_manufacturer_ops *ops;
|
||||
};
|
||||
|
||||
const struct nand_manufacturer *nand_get_manufacturer(u8 id);
|
||||
|
||||
static inline const char *
|
||||
nand_manufacturer_name(const struct nand_manufacturer *manufacturer)
|
||||
{
|
||||
return manufacturer ? manufacturer->name : "Unknown";
|
||||
}
|
||||
|
||||
extern struct nand_flash_dev nand_flash_ids[];
|
||||
|
||||
extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops;
|
||||
extern const struct nand_manufacturer_ops samsung_nand_manuf_ops;
|
||||
extern const struct nand_manufacturer_ops hynix_nand_manuf_ops;
|
||||
extern const struct nand_manufacturer_ops micron_nand_manuf_ops;
|
||||
extern const struct nand_manufacturer_ops amd_nand_manuf_ops;
|
||||
extern const struct nand_manufacturer_ops macronix_nand_manuf_ops;
|
||||
|
||||
int nand_create_bbt(struct nand_chip *chip);
|
||||
int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);
|
||||
int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs);
|
||||
int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
|
||||
int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
|
||||
int allowbbt);
|
||||
|
||||
/**
|
||||
* struct platform_nand_chip - chip level device structure
|
||||
* @nr_chips: max. number of chips to scan for
|
||||
* @chip_offset: chip number offset
|
||||
* @nr_partitions: number of partitions pointed to by partitions (or zero)
|
||||
* @partitions: mtd partition list
|
||||
* @chip_delay: R/B delay value in us
|
||||
* @options: Option flags, e.g. 16bit buswidth
|
||||
* @bbt_options: BBT option flags, e.g. NAND_BBT_USE_FLASH
|
||||
* @part_probe_types: NULL-terminated array of probe types
|
||||
*/
|
||||
struct platform_nand_chip {
|
||||
int nr_chips;
|
||||
int chip_offset;
|
||||
int nr_partitions;
|
||||
struct mtd_partition *partitions;
|
||||
int chip_delay;
|
||||
unsigned int options;
|
||||
unsigned int bbt_options;
|
||||
const char **part_probe_types;
|
||||
};
|
||||
|
||||
/* Keep gcc happy */
|
||||
struct platform_device;
|
||||
|
||||
/**
|
||||
* struct platform_nand_ctrl - controller level device structure
|
||||
* @probe: platform specific function to probe/setup hardware
|
||||
* @remove: platform specific function to remove/teardown hardware
|
||||
* @dev_ready: platform specific function to read ready/busy pin
|
||||
* @select_chip: platform specific chip select function
|
||||
* @cmd_ctrl: platform specific function for controlling
|
||||
* ALE/CLE/nCE. Also used to write command and address
|
||||
* @write_buf: platform specific function for write buffer
|
||||
* @read_buf: platform specific function for read buffer
|
||||
* @priv: private data to transport driver specific settings
|
||||
*
|
||||
* All fields are optional and depend on the hardware driver requirements
|
||||
*/
|
||||
struct platform_nand_ctrl {
|
||||
int (*probe)(struct platform_device *pdev);
|
||||
void (*remove)(struct platform_device *pdev);
|
||||
int (*dev_ready)(struct mtd_info *mtd);
|
||||
void (*select_chip)(struct mtd_info *mtd, int chip);
|
||||
void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
|
||||
void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
|
||||
void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct platform_nand_data - container structure for platform-specific data
|
||||
* @chip: chip level chip structure
|
||||
* @ctrl: controller level device structure
|
||||
*/
|
||||
struct platform_nand_data {
|
||||
struct platform_nand_chip chip;
|
||||
struct platform_nand_ctrl ctrl;
|
||||
};
|
||||
|
||||
/* return the supported asynchronous timing mode. */
|
||||
static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
|
||||
{
|
||||
if (!chip->parameters.onfi)
|
||||
return ONFI_TIMING_MODE_UNKNOWN;
|
||||
|
||||
return chip->parameters.onfi->async_timing_mode;
|
||||
}
|
||||
|
||||
int onfi_fill_data_interface(struct nand_chip *chip,
|
||||
enum nand_data_interface_type type,
|
||||
int timing_mode);
|
||||
|
||||
/*
|
||||
* Check if it is a SLC nand.
|
||||
@@ -1658,9 +1263,6 @@ static inline int nand_opcode_8bits(unsigned int command)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get timing characteristics from ONFI timing mode. */
|
||||
const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);
|
||||
|
||||
int nand_check_erased_ecc_chunk(void *data, int datalen,
|
||||
void *ecc, int ecclen,
|
||||
void *extraoob, int extraooblen,
|
||||
@@ -1670,37 +1272,22 @@ int nand_ecc_choose_conf(struct nand_chip *chip,
|
||||
const struct nand_ecc_caps *caps, int oobavail);
|
||||
|
||||
/* Default write_oob implementation */
|
||||
int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page);
|
||||
|
||||
/* Default write_oob syndrome implementation */
|
||||
int nand_write_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
int page);
|
||||
int nand_write_oob_std(struct nand_chip *chip, int page);
|
||||
|
||||
/* Default read_oob implementation */
|
||||
int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page);
|
||||
int nand_read_oob_std(struct nand_chip *chip, int page);
|
||||
|
||||
/* Default read_oob syndrome implementation */
|
||||
int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
int page);
|
||||
|
||||
/* Wrapper to use in order for controllers/vendors to GET/SET FEATURES */
|
||||
int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param);
|
||||
int nand_set_features(struct nand_chip *chip, int addr, u8 *subfeature_param);
|
||||
/* Stub used by drivers that do not support GET/SET FEATURES operations */
|
||||
int nand_get_set_features_notsupp(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
int addr, u8 *subfeature_param);
|
||||
int nand_get_set_features_notsupp(struct nand_chip *chip, int addr,
|
||||
u8 *subfeature_param);
|
||||
|
||||
/* Default read_page_raw implementation */
|
||||
int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
uint8_t *buf, int oob_required, int page);
|
||||
int nand_read_page_raw_notsupp(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
u8 *buf, int oob_required, int page);
|
||||
int nand_read_page_raw(struct nand_chip *chip, uint8_t *buf, int oob_required,
|
||||
int page);
|
||||
|
||||
/* Default write_page_raw implementation */
|
||||
int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
const uint8_t *buf, int oob_required, int page);
|
||||
int nand_write_page_raw_notsupp(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
const u8 *buf, int oob_required, int page);
|
||||
int nand_write_page_raw(struct nand_chip *chip, const uint8_t *buf,
|
||||
int oob_required, int page);
|
||||
|
||||
/* Reset and initialize a NAND device */
|
||||
int nand_reset(struct nand_chip *chip, int chipnr);
|
||||
@@ -1710,7 +1297,6 @@ int nand_reset_op(struct nand_chip *chip);
|
||||
int nand_readid_op(struct nand_chip *chip, u8 addr, void *buf,
|
||||
unsigned int len);
|
||||
int nand_status_op(struct nand_chip *chip, u8 *status);
|
||||
int nand_exit_status_op(struct nand_chip *chip);
|
||||
int nand_erase_op(struct nand_chip *chip, unsigned int eraseblock);
|
||||
int nand_read_page_op(struct nand_chip *chip, unsigned int page,
|
||||
unsigned int offset_in_page, void *buf, unsigned int len);
|
||||
@@ -1734,16 +1320,25 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
|
||||
int nand_write_data_op(struct nand_chip *chip, const void *buf,
|
||||
unsigned int len, bool force_8bit);
|
||||
|
||||
/* Scan and identify a NAND device */
|
||||
int nand_scan_with_ids(struct nand_chip *chip, unsigned int max_chips,
|
||||
struct nand_flash_dev *ids);
|
||||
|
||||
static inline int nand_scan(struct nand_chip *chip, unsigned int max_chips)
|
||||
{
|
||||
return nand_scan_with_ids(chip, max_chips, NULL);
|
||||
}
|
||||
|
||||
/* Internal helper for board drivers which need to override command function */
|
||||
void nand_wait_ready(struct nand_chip *chip);
|
||||
|
||||
/*
|
||||
* Free resources held by the NAND device, must be called on error after a
|
||||
* sucessful nand_scan().
|
||||
*/
|
||||
void nand_cleanup(struct nand_chip *chip);
|
||||
/* Unregister the MTD device and calls nand_cleanup() */
|
||||
void nand_release(struct mtd_info *mtd);
|
||||
|
||||
/* Default extended ID decoding function */
|
||||
void nand_decode_ext_id(struct nand_chip *chip);
|
||||
void nand_release(struct nand_chip *chip);
|
||||
|
||||
/*
|
||||
* External helper for controller drivers that have to implement the WAITRDY
|
||||
|
@@ -256,6 +256,9 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
|
||||
#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
|
||||
#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
|
||||
|
||||
extern bool of_node_name_eq(const struct device_node *np, const char *name);
|
||||
extern bool of_node_name_prefix(const struct device_node *np, const char *prefix);
|
||||
|
||||
static inline const char *of_node_full_name(const struct device_node *np)
|
||||
{
|
||||
return np ? np->full_name : "<no-node>";
|
||||
@@ -290,6 +293,8 @@ extern struct device_node *of_get_next_child(const struct device_node *node,
|
||||
extern struct device_node *of_get_next_available_child(
|
||||
const struct device_node *node, struct device_node *prev);
|
||||
|
||||
extern struct device_node *of_get_compatible_child(const struct device_node *parent,
|
||||
const char *compatible);
|
||||
extern struct device_node *of_get_child_by_name(const struct device_node *node,
|
||||
const char *name);
|
||||
|
||||
@@ -561,6 +566,16 @@ static inline struct device_node *to_of_node(const struct fwnode_handle *fwnode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool of_node_name_eq(const struct device_node *np, const char *name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool of_node_name_prefix(const struct device_node *np, const char *prefix)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline const char* of_node_full_name(const struct device_node *np)
|
||||
{
|
||||
return "<no-node>";
|
||||
@@ -632,6 +647,12 @@ static inline bool of_have_populated_dt(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline struct device_node *of_get_compatible_child(const struct device_node *parent,
|
||||
const char *compatible)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct device_node *of_get_child_by_name(
|
||||
const struct device_node *node,
|
||||
const char *name)
|
||||
@@ -967,6 +988,18 @@ static inline struct device_node *of_find_matching_node(
|
||||
return of_find_matching_node_and_match(from, matches, NULL);
|
||||
}
|
||||
|
||||
static inline const char *of_node_get_device_type(const struct device_node *np)
|
||||
{
|
||||
return of_get_property(np, "type", NULL);
|
||||
}
|
||||
|
||||
static inline bool of_node_is_type(const struct device_node *np, const char *type)
|
||||
{
|
||||
const char *match = of_node_get_device_type(np);
|
||||
|
||||
return np && match && type && !strcmp(match, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* of_property_count_u8_elems - Count the number of u8 elements in a property
|
||||
*
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Driver for Texas Instruments INA219, INA226 power monitor chips
|
||||
*
|
||||
* Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
|
||||
* Copyright (C) 2012 Lothar Felten <lothar.felten@gmail.com>
|
||||
*
|
||||
* 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
|
||||
|
@@ -408,13 +408,7 @@ struct qc_type_state {
|
||||
|
||||
struct qc_state {
|
||||
unsigned int s_incoredqs; /* Number of dquots in core */
|
||||
/*
|
||||
* Per quota type information. The array should really have
|
||||
* max(MAXQUOTAS, XQM_MAXQUOTAS) entries. BUILD_BUG_ON in
|
||||
* quota_getinfo() makes sure XQM_MAXQUOTAS is large enough. Once VFS
|
||||
* supports project quotas, this can be changed to MAXQUOTAS
|
||||
*/
|
||||
struct qc_type_state s_state[XQM_MAXQUOTAS];
|
||||
struct qc_type_state s_state[MAXQUOTAS]; /* Per quota type information */
|
||||
};
|
||||
|
||||
/* Structure for communicating via ->set_info */
|
||||
|
Reference in New Issue
Block a user