From patchwork Fri Mar 29 07:28:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 161400 Delivered-To: patch@linaro.org Received: by 2002:a02:c6d8:0:0:0:0:0 with SMTP id r24csp1696853jan; Fri, 29 Mar 2019 00:29:43 -0700 (PDT) X-Google-Smtp-Source: APXvYqzu2faGylGYvdRxcKIIYcMNdkCEGywYMTzCCRsdil88iFcKPmoT/omfsAAgQ/YyFHK5ayit X-Received: by 2002:a63:441b:: with SMTP id r27mr42659261pga.36.1553844583301; Fri, 29 Mar 2019 00:29:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553844583; cv=none; d=google.com; s=arc-20160816; b=00SudhMvIul5HOLin1IPdqdEiiLnq85RqSMlFiyvNoYKOO+DEH9vomJCV2QXQtTTf1 J4tNcQUjwgJGf7Qk0hb3qZHKMa0USIK2tbnCMZRDvEVYx7zG2HaBZ3Aa8V5Ep4bCDFL7 8g9eASDQgCauatnRnK7njq6hwgdcRtutlmSLibaXgQ0yBZHV49R/qf9IIMt4a9hXjeB7 /JIhlBDnwIln+Tv3LR7WLuYU6bhJUTxBlnwOjpk/9WLTgOU9rLMPyNreDD4fl4FfDK8J wu/ASKyMDcvF5GZRI2jfJAC+Qt8Kje9fwP14VrUY/R5syIOfk8vlw3AX4wb7NyOgR1FC jxQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:dkim-filter; bh=z9+eFqBNWuKqrzFd3y8VkzuoTrY+iDF+DqOZ8Outmoc=; b=LROF1GA9uA8b96bcIQvQiCMKmbIBjiOnOaP7gkkrfwnsf1uQLp4a/AngnyBLAOIaYe +M7igSLOpFRgbdtpZ1gLamSy9kWDuHxc9xRkZOs5K9MeAvRJYzhOZUhqgNnpM78OcLYe ozfqGEKAWa0omQtbUevsCinxFciwri2y8ABFvvF/no2FF5J602pr+zKohh+qoLxwkbaR yuKmNcPPF4xr05u8Gq20PU2fmG6q7tnAP34PnKXD6UGfA1rPAKPnnMVPTm6AVh0spewu 06oi2Det7zyEUlXI+ZHUu2+b0hXHcwGqFaGp7X2S6bYPenTNaAsJPwcb1wcINwBjc/kX xRdA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nifty.com header.s=dec2015msa header.b=RmkmDo67; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v2si1257972pgh.356.2019.03.29.00.29.42; Fri, 29 Mar 2019 00:29:43 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@nifty.com header.s=dec2015msa header.b=RmkmDo67; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728931AbfC2H3l (ORCPT + 31 others); Fri, 29 Mar 2019 03:29:41 -0400 Received: from conuserg-10.nifty.com ([210.131.2.77]:64946 "EHLO conuserg-10.nifty.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728868AbfC2H3k (ORCPT ); Fri, 29 Mar 2019 03:29:40 -0400 Received: from grover.tkatk1.zaq.ne.jp (zaqdadce369.zaq.ne.jp [218.220.227.105]) (authenticated) by conuserg-10.nifty.com with ESMTP id x2T7SQaB002537; Fri, 29 Mar 2019 16:28:30 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-10.nifty.com x2T7SQaB002537 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1553844510; bh=z9+eFqBNWuKqrzFd3y8VkzuoTrY+iDF+DqOZ8Outmoc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RmkmDo67VYUO/YS1e0u9r1d5yIzijan1TjQ0T1myS7dDVYfyjlSHE2IW3lQ70SA7z QFL3pG8nUtZSzzLAzQeF1rzNjHy9RNZUb47OJqUVOKVYj3TVF/BAv0nWoa3LlhAafu GHYH37z0cQkp7l8u7Xk/OO/rQvan5InCPwLctOgODf9lS+bmkD0W6AzFF0EWEb1h3h yd5OOf7VZAukEN+TeGV/pzGrqlLQOrvyudA8eA2S61fpVVU2dQW2ZlYaq+En8moQKQ U5uNX9PWyfcu3D1OJzqqaK1VvrgshG8NbJTdPVN1fp17EzIX0y2dyg0Hd2lSQ6DQpl UXhXJhkvWUxVQ== X-Nifty-SrcIP: [218.220.227.105] From: Masahiro Yamada To: linux-mtd@lists.infradead.org, Miquel Raynal Cc: Masahiro Yamada , Brian Norris , linux-kernel@vger.kernel.org, Marek Vasut , Richard Weinberger , David Woodhouse , Boris Brezillon Subject: [PATCH v4 4/9] mtd: rawnand: denali: switch over to ->exec_op() from legacy hooks Date: Fri, 29 Mar 2019 16:28:16 +0900 Message-Id: <1553844501-7119-5-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1553844501-7119-1-git-send-email-yamada.masahiro@socionext.com> References: <1553844501-7119-1-git-send-email-yamada.masahiro@socionext.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Implement ->exec_op(), and remove the deprecated hooks. Signed-off-by: Masahiro Yamada --- Changes in v4: - add denali_exec_in() and denali_exec_out() - avoid ternary operator to select function Changes in v3: - Fix byte-swap in denali_exec_in16() Changes in v2: None drivers/mtd/nand/raw/denali.c | 251 ++++++++++++++++++++++++------------------ 1 file changed, 143 insertions(+), 108 deletions(-) -- 2.7.4 diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index bf968cc..eaf4a36 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c @@ -206,85 +206,11 @@ static uint32_t denali_wait_for_irq(struct denali_nand_info *denali, return denali->irq_status; } -static void denali_read_buf(struct nand_chip *chip, uint8_t *buf, int len) +static void denali_select_target(struct nand_chip *chip, int cs) { - struct mtd_info *mtd = nand_to_mtd(chip); - struct denali_nand_info *denali = mtd_to_denali(mtd); - u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali); - int i; - - for (i = 0; i < len; i++) - buf[i] = denali->host_read(denali, addr); -} - -static void denali_write_buf(struct nand_chip *chip, const uint8_t *buf, - int len) -{ - struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); - u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali); - int i; - - for (i = 0; i < len; i++) - denali->host_write(denali, addr, buf[i]); -} - -static void denali_read_buf16(struct nand_chip *chip, uint8_t *buf, int len) -{ - struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); - u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali); - uint16_t *buf16 = (uint16_t *)buf; - int i; - - for (i = 0; i < len / 2; i++) - buf16[i] = denali->host_read(denali, addr); -} - -static void denali_write_buf16(struct nand_chip *chip, const uint8_t *buf, - int len) -{ - struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); - u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali); - const uint16_t *buf16 = (const uint16_t *)buf; - int i; - - for (i = 0; i < len / 2; i++) - denali->host_write(denali, addr, buf16[i]); -} - -static uint8_t denali_read_byte(struct nand_chip *chip) -{ - uint8_t byte; - - denali_read_buf(chip, &byte, 1); - - return byte; -} - -static void denali_write_byte(struct nand_chip *chip, uint8_t byte) -{ - denali_write_buf(chip, &byte, 1); -} - -static void denali_cmd_ctrl(struct nand_chip *chip, int dat, unsigned int ctrl) -{ - struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); - uint32_t type; - - if (ctrl & NAND_CLE) - type = DENALI_MAP11_CMD; - else if (ctrl & NAND_ALE) - type = DENALI_MAP11_ADDR; - else - return; - - /* - * Some commands are followed by chip->legacy.waitfunc. - * irq_status must be cleared here to catch the R/B# interrupt later. - */ - if (ctrl & NAND_CTRL_CHANGE) - denali_reset_irq(denali); + struct denali_nand_info *denali = to_denali(chip); - denali->host_write(denali, DENALI_BANK(denali) | type, dat); + denali->active_bank = cs; } static int denali_change_column(struct nand_chip *chip, unsigned int offset, @@ -772,6 +698,8 @@ static int denali_page_xfer(struct nand_chip *chip, void *buf, size_t size, { struct denali_nand_info *denali = to_denali(chip); + denali_select_target(chip, chip->cur_cs); + if (denali->dma_avail) return denali_dma_xfer(denali, buf, size, page, write); else @@ -819,24 +747,6 @@ static int denali_write_page(struct nand_chip *chip, const uint8_t *buf, return denali_page_xfer(chip, (void *)buf, mtd->writesize, page, 1); } -static void denali_select_chip(struct nand_chip *chip, int cs) -{ - struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); - - denali->active_bank = cs; -} - -static int denali_waitfunc(struct nand_chip *chip) -{ - struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); - uint32_t irq_status; - - /* R/B# pin transitioned from low to high? */ - irq_status = denali_wait_for_irq(denali, INTR__INT_ACT); - - return irq_status & INTR__INT_ACT ? 0 : NAND_STATUS_FAIL; -} - static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, const struct nand_data_interface *conf) { @@ -1149,13 +1059,6 @@ static int denali_attach_chip(struct nand_chip *chip) mtd_set_ooblayout(mtd, &denali_ooblayout_ops); - if (chip->options & NAND_BUSWIDTH_16) { - chip->legacy.read_buf = denali_read_buf16; - chip->legacy.write_buf = denali_write_buf16; - } else { - chip->legacy.read_buf = denali_read_buf; - chip->legacy.write_buf = denali_write_buf; - } chip->ecc.read_page = denali_read_page; chip->ecc.read_page_raw = denali_read_page_raw; chip->ecc.write_page = denali_write_page; @@ -1170,8 +1073,146 @@ static int denali_attach_chip(struct nand_chip *chip) return 0; } +static void denali_exec_in8(struct denali_nand_info *denali, u32 type, + u8 *buf, unsigned int len) +{ + int i; + + for (i = 0; i < len; i++) + buf[i] = denali->host_read(denali, type | DENALI_BANK(denali)); +} + +static void denali_exec_in16(struct denali_nand_info *denali, u32 type, + u8 *buf, unsigned int len) +{ + u32 data; + int i; + + for (i = 0; i < len; i += 2) { + data = denali->host_read(denali, type | DENALI_BANK(denali)); + /* bit 31:24 and 15:8 are used for DDR */ + buf[i] = data; + buf[i + 1] = data >> 16; + } +} + +static void denali_exec_in(struct denali_nand_info *denali, u32 type, + u8 *buf, unsigned int len, bool width16) +{ + if (width16) + denali_exec_in16(denali, type, buf, len); + else + denali_exec_in8(denali, type, buf, len); +} + +static void denali_exec_out8(struct denali_nand_info *denali, u32 type, + const u8 *buf, unsigned int len) +{ + int i; + + for (i = 0; i < len; i++) + denali->host_write(denali, type | DENALI_BANK(denali), buf[i]); +} + +static void denali_exec_out16(struct denali_nand_info *denali, u32 type, + const u8 *buf, unsigned int len) +{ + int i; + + for (i = 0; i < len; i += 2) + denali->host_write(denali, type | DENALI_BANK(denali), + buf[i + 1] << 16 | buf[i]); +} + +static void denali_exec_out(struct denali_nand_info *denali, u32 type, + const u8 *buf, unsigned int len, bool width16) +{ + if (width16) + denali_exec_out16(denali, type, buf, len); + else + denali_exec_out8(denali, type, buf, len); +} + +static int denali_exec_waitrdy(struct denali_nand_info *denali) +{ + u32 irq_stat; + + /* R/B# pin transitioned from low to high? */ + irq_stat = denali_wait_for_irq(denali, INTR__INT_ACT); + + /* Just in case nand_operation has multiple NAND_OP_WAITRDY_INSTR. */ + denali_reset_irq(denali); + + return irq_stat & INTR__INT_ACT ? 0 : -EIO; +} + +static int denali_exec_instr(struct nand_chip *chip, + const struct nand_op_instr *instr) +{ + struct denali_nand_info *denali = to_denali(chip); + + switch (instr->type) { + case NAND_OP_CMD_INSTR: + denali_exec_out8(denali, DENALI_MAP11_CMD, + &instr->ctx.cmd.opcode, 1); + return 0; + case NAND_OP_ADDR_INSTR: + denali_exec_out8(denali, DENALI_MAP11_ADDR, + instr->ctx.addr.addrs, + instr->ctx.addr.naddrs); + return 0; + case NAND_OP_DATA_IN_INSTR: + denali_exec_in(denali, DENALI_MAP11_DATA, + instr->ctx.data.buf.in, + instr->ctx.data.len, + !instr->ctx.data.force_8bit && + chip->options & NAND_BUSWIDTH_16); + return 0; + case NAND_OP_DATA_OUT_INSTR: + denali_exec_out(denali, DENALI_MAP11_DATA, + instr->ctx.data.buf.out, + instr->ctx.data.len, + !instr->ctx.data.force_8bit && + chip->options & NAND_BUSWIDTH_16); + return 0; + case NAND_OP_WAITRDY_INSTR: + return denali_exec_waitrdy(denali); + default: + WARN_ONCE(1, "unsupported NAND instruction type: %d\n", + instr->type); + + return -EINVAL; + } +} + +static int denali_exec_op(struct nand_chip *chip, + const struct nand_operation *op, bool check_only) +{ + int i, ret; + + if (check_only) + return 0; + + denali_select_target(chip, op->cs); + + /* + * Some commands contain NAND_OP_WAITRDY_INSTR. + * irq must be cleared here to catch the R/B# interrupt there. + */ + denali_reset_irq(to_denali(chip)); + + for (i = 0; i < op->ninstrs; i++) { + ret = denali_exec_instr(chip, &op->instrs[i]); + if (ret) + return ret; + } + + return 0; +} + static const struct nand_controller_ops denali_controller_ops = { .attach_chip = denali_attach_chip, + .exec_op = denali_exec_op, .setup_data_interface = denali_setup_data_interface, }; @@ -1206,12 +1247,6 @@ int denali_init(struct denali_nand_info *denali) if (!mtd->name) mtd->name = "denali-nand"; - chip->legacy.select_chip = denali_select_chip; - chip->legacy.read_byte = denali_read_byte; - chip->legacy.write_byte = denali_write_byte; - chip->legacy.cmd_ctrl = denali_cmd_ctrl; - chip->legacy.waitfunc = denali_waitfunc; - if (features & FEATURES__INDEX_ADDR) { denali->host_read = denali_indexed_read; denali->host_write = denali_indexed_write;