diff options
Diffstat (limited to 'drivers/mtd/nand/ndfc.c')
| -rw-r--r-- | drivers/mtd/nand/ndfc.c | 65 | 
1 files changed, 36 insertions, 29 deletions
| diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index bbe6d451290d..ea2dea8a9c88 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -33,6 +33,7 @@  #include <linux/of_platform.h>  #include <asm/io.h> +#define NDFC_MAX_CS    4  struct ndfc_controller {  	struct platform_device *ofdev; @@ -41,17 +42,16 @@ struct ndfc_controller {  	struct nand_chip chip;  	int chip_select;  	struct nand_hw_control ndfc_control; -#ifdef CONFIG_MTD_PARTITIONS  	struct mtd_partition *parts; -#endif  }; -static struct ndfc_controller ndfc_ctrl; +static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS];  static void ndfc_select_chip(struct mtd_info *mtd, int chip)  {  	uint32_t ccr; -	struct ndfc_controller *ndfc = &ndfc_ctrl; +	struct nand_chip *nchip = mtd->priv; +	struct ndfc_controller *ndfc = nchip->priv;  	ccr = in_be32(ndfc->ndfcbase + NDFC_CCR);  	if (chip >= 0) { @@ -64,7 +64,8 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip)  static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)  { -	struct ndfc_controller *ndfc = &ndfc_ctrl; +	struct nand_chip *chip = mtd->priv; +	struct ndfc_controller *ndfc = chip->priv;  	if (cmd == NAND_CMD_NONE)  		return; @@ -77,7 +78,8 @@ static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)  static int ndfc_ready(struct mtd_info *mtd)  { -	struct ndfc_controller *ndfc = &ndfc_ctrl; +	struct nand_chip *chip = mtd->priv; +	struct ndfc_controller *ndfc = chip->priv;  	return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY;  } @@ -85,7 +87,8 @@ static int ndfc_ready(struct mtd_info *mtd)  static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)  {  	uint32_t ccr; -	struct ndfc_controller *ndfc = &ndfc_ctrl; +	struct nand_chip *chip = mtd->priv; +	struct ndfc_controller *ndfc = chip->priv;  	ccr = in_be32(ndfc->ndfcbase + NDFC_CCR);  	ccr |= NDFC_CCR_RESET_ECC; @@ -96,7 +99,8 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)  static int ndfc_calculate_ecc(struct mtd_info *mtd,  			      const u_char *dat, u_char *ecc_code)  { -	struct ndfc_controller *ndfc = &ndfc_ctrl; +	struct nand_chip *chip = mtd->priv; +	struct ndfc_controller *ndfc = chip->priv;  	uint32_t ecc;  	uint8_t *p = (uint8_t *)&ecc; @@ -119,7 +123,8 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd,   */  static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)  { -	struct ndfc_controller *ndfc = &ndfc_ctrl; +	struct nand_chip *chip = mtd->priv; +	struct ndfc_controller *ndfc = chip->priv;  	uint32_t *p = (uint32_t *) buf;  	for(;len > 0; len -= 4) @@ -128,7 +133,8 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)  static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)  { -	struct ndfc_controller *ndfc = &ndfc_ctrl; +	struct nand_chip *chip = mtd->priv; +	struct ndfc_controller *ndfc = chip->priv;  	uint32_t *p = (uint32_t *) buf;  	for(;len > 0; len -= 4) @@ -137,7 +143,8 @@ static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)  static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)  { -	struct ndfc_controller *ndfc = &ndfc_ctrl; +	struct nand_chip *chip = mtd->priv; +	struct ndfc_controller *ndfc = chip->priv;  	uint32_t *p = (uint32_t *) buf;  	for(;len > 0; len -= 4) @@ -152,13 +159,11 @@ static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)  static int ndfc_chip_init(struct ndfc_controller *ndfc,  			  struct device_node *node)  { -#ifdef CONFIG_MTD_PARTITIONS  #ifdef CONFIG_MTD_CMDLINE_PARTS  	static const char *part_types[] = { "cmdlinepart", NULL };  #else  	static const char *part_types[] = { NULL };  #endif -#endif  	struct device_node *flash_np;  	struct nand_chip *chip = &ndfc->chip;  	int ret; @@ -179,6 +184,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,  	chip->ecc.mode = NAND_ECC_HW;  	chip->ecc.size = 256;  	chip->ecc.bytes = 3; +	chip->priv = ndfc;  	ndfc->mtd.priv = chip;  	ndfc->mtd.owner = THIS_MODULE; @@ -198,25 +204,18 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,  	if (ret)  		goto err; -#ifdef CONFIG_MTD_PARTITIONS  	ret = parse_mtd_partitions(&ndfc->mtd, part_types, &ndfc->parts, 0);  	if (ret < 0)  		goto err; -#ifdef CONFIG_MTD_OF_PARTS  	if (ret == 0) {  		ret = of_mtd_parse_partitions(&ndfc->ofdev->dev, flash_np,  					      &ndfc->parts);  		if (ret < 0)  			goto err;  	} -#endif -	if (ret > 0) -		ret = add_mtd_partitions(&ndfc->mtd, ndfc->parts, ret); -	else -#endif -		ret = add_mtd_device(&ndfc->mtd); +	ret = mtd_device_register(&ndfc->mtd, ndfc->parts, ret);  err:  	of_node_put(flash_np); @@ -227,15 +226,10 @@ err:  static int __devinit ndfc_probe(struct platform_device *ofdev)  { -	struct ndfc_controller *ndfc = &ndfc_ctrl; +	struct ndfc_controller *ndfc;  	const __be32 *reg;  	u32 ccr; -	int err, len; - -	spin_lock_init(&ndfc->ndfc_control.lock); -	init_waitqueue_head(&ndfc->ndfc_control.wq); -	ndfc->ofdev = ofdev; -	dev_set_drvdata(&ofdev->dev, ndfc); +	int err, len, cs;  	/* Read the reg property to get the chip select */  	reg = of_get_property(ofdev->dev.of_node, "reg", &len); @@ -243,7 +237,20 @@ static int __devinit ndfc_probe(struct platform_device *ofdev)  		dev_err(&ofdev->dev, "unable read reg property (%d)\n", len);  		return -ENOENT;  	} -	ndfc->chip_select = be32_to_cpu(reg[0]); + +	cs = be32_to_cpu(reg[0]); +	if (cs >= NDFC_MAX_CS) { +		dev_err(&ofdev->dev, "invalid CS number (%d)\n", cs); +		return -EINVAL; +	} + +	ndfc = &ndfc_ctrl[cs]; +	ndfc->chip_select = cs; + +	spin_lock_init(&ndfc->ndfc_control.lock); +	init_waitqueue_head(&ndfc->ndfc_control.wq); +	ndfc->ofdev = ofdev; +	dev_set_drvdata(&ofdev->dev, ndfc);  	ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0);  	if (!ndfc->ndfcbase) { |