pastebin

Paste #135875: Untitled ASCII paste by 90.63.216.87

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 649ba8200832..d8330d8cab82 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1165,6 +1165,101 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
 	return exec_cmd;
 }
 
+static int pxa3xx_nand_set_features(struct mtd_info *mtd,
+				    struct nand_chip *chip, int addr,
+				    u8 *subfeature_param)
+{
+	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
+	struct pxa3xx_nand_info *info = host->info_data;
+	int ret = 0;
+
+	/*
+	 * There may be different NAND chip hooked to
+	 * different chip select, so check whether
+	 * chip select has been changed, if yes, reset the timing
+	 */
+	if (info->cs != host->cs) {
+		info->cs = host->cs;
+		nand_writel(info, NDTR0CS0, info->ndtr0cs0);
+		nand_writel(info, NDTR1CS0, info->ndtr1cs0);
+	}
+
+	prepare_start_command(info, NAND_CMD_SET_FEATURES);
+
+	info->buf_count = 4;
+	info->ndcb0 = NDCB0_CMD_TYPE(1) | NDCB0_ADDR_CYC(1) | NDCB0_LEN_OVRD |
+		      NAND_CMD_SET_FEATURES | (info->cs ? NDCB0_CSEL : 0);
+	info->ndcb1 = (addr & 0xFF);
+	info->ndcb3 = 4;
+	info->step_chunk_size = 4;
+	memcpy(info->data_buff, subfeature_param, 4);
+
+	init_completion(&info->cmd_complete);
+	init_completion(&info->dev_ready);
+	info->need_wait = 1;
+	pxa3xx_nand_start(info);
+
+	if (!wait_for_completion_timeout(&info->cmd_complete,
+					 CHIP_DELAY_TIMEOUT)) {
+		dev_err(&info->pdev->dev, "Wait time out!!!\n");
+		/* Stop State Machine for next command cycle */
+		pxa3xx_nand_stop(info);
+		ret = -ETIMEDOUT;
+	}
+
+	info->state = STATE_IDLE;
+
+	return ret;
+}
+
+static int pxa3xx_nand_get_features(struct mtd_info *mtd,
+				    struct nand_chip *chip, int addr,
+				    u8 *subfeature_param)
+{
+	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
+	struct pxa3xx_nand_info *info = host->info_data;
+	int ret = 0;
+
+	/*
+	 * There may be different NAND chip hooked to
+	 * different chip select, so check whether
+	 * chip select has been changed, if yes, reset the timing
+	 */
+	if (info->cs != host->cs) {
+		info->cs = host->cs;
+		nand_writel(info, NDTR0CS0, info->ndtr0cs0);
+		nand_writel(info, NDTR1CS0, info->ndtr1cs0);
+	}
+
+	prepare_start_command(info, NAND_CMD_GET_FEATURES);
+
+	info->buf_count = 4;
+	info->ndcb0 = NDCB0_CMD_TYPE(0) | NDCB0_ADDR_CYC(1) | NDCB0_LEN_OVRD |
+		      NAND_CMD_GET_FEATURES | (info->cs ? NDCB0_CSEL : 0);
+	info->ndcb1 = (addr & 0xFF);
+	info->ndcb3 = 4;
+	info->step_chunk_size = 4;
+
+	init_completion(&info->cmd_complete);
+	init_completion(&info->dev_ready);
+	info->need_wait = 1;
+	pxa3xx_nand_start(info);
+
+	if (!wait_for_completion_timeout(&info->cmd_complete,
+					 CHIP_DELAY_TIMEOUT)) {
+		dev_err(&info->pdev->dev, "Wait time out!!!\n");
+		/* Stop State Machine for next command cycle */
+		pxa3xx_nand_stop(info);
+		ret = -ETIMEDOUT;
+	} else {
+		memcpy(subfeature_param, info->data_buff, 4);
+	}
+
+	info->state = STATE_IDLE;
+
+	return ret;
+}
+
 static void nand_cmdfunc(struct mtd_info *mtd, unsigned command,
 			 int column, int page_addr)
 {
@@ -1812,6 +1907,8 @@ static int alloc_nand_resource(struct platform_device *pdev)
 		chip->write_buf		= pxa3xx_nand_write_buf;
 		chip->options		|= NAND_NO_SUBPAGE_WRITE;
 		chip->cmdfunc		= nand_cmdfunc;
+		chip->onfi_set_features	= pxa3xx_nand_set_features;
+		chip->onfi_get_features	= pxa3xx_nand_get_features;
 	}
 
 	nand_hw_control_init(chip->controller);

Private
Wrap long lines

1 + 5 =