From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751938AbcCaH2r (ORCPT ); Thu, 31 Mar 2016 03:28:47 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:19283 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750941AbcCaH2p (ORCPT ); Thu, 31 Mar 2016 03:28:45 -0400 Subject: Re: [RESEND PATCH v9] mtd: spi-nor: add hisilicon spi-nor flash controller driver To: , , , , , , , , References: <1458979861-3619-1-git-send-email-xuejiancheng@huawei.com> CC: , , , , , , , , , , From: Jiancheng Xue Message-ID: <56FCD0BD.4010505@huawei.com> Date: Thu, 31 Mar 2016 15:24:45 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:38.0) Gecko/20100101 Thunderbird/38.5.0 MIME-Version: 1.0 In-Reply-To: <1458979861-3619-1-git-send-email-xuejiancheng@huawei.com> Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 7bit X-Originating-IP: [10.67.217.211] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090205.56FCD0CA.0097,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 11e60d3e9658208714d00c014a8c48db Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi all, I'll highly appreciated any of your comments. On 2016/3/26 16:11, Jiancheng Xue wrote: > Add hisilicon spi-nor flash controller driver > [...] > +static int hisi_spi_nor_read(struct spi_nor *nor, loff_t from, size_t len, > + size_t *retlen, u_char *read_buf) > +{ > + struct hifmc_priv *priv = nor->priv; > + struct hifmc_host *host = priv->host; > + unsigned char *ptr = read_buf; > + size_t actual_len; > + > + *retlen = 0; > + while (len > 0) { > + actual_len = (len >= HIFMC_DMA_MAX_LEN) > + ? HIFMC_DMA_MAX_LEN : len; > + hisi_spi_nor_dma_transfer(nor, from, host->dma_buffer, > + actual_len, FMC_OP_READ); > + memcpy(ptr, host->buffer, actual_len); > + ptr += actual_len; > + from += actual_len; > + len -= actual_len; > + *retlen += actual_len; > + } > + > + return 0; > +} For easy understanding, the read function will be changed like below: static int hisi_spi_nor_read(struct spi_nor *nor, loff_t from, size_t len, size_t *retlen, u_char *read_buf) { struct hifmc_priv *priv = nor->priv; struct hifmc_host *host = priv->host; int i; /* read all bytes in only one time */ if (len <= HIFMC_DMA_MAX_LEN) { hisi_spi_nor_dma_transfer(nor, from, host->dma_buffer, len, FMC_OP_READ); memcpy(read_buf, host->buffer, len); } else { /* read HIFMC_DMA_MAX_LEN bytes at a time */ for (i = 0; i < len; i += HIFMC_DMA_MAX_LEN) { hisi_spi_nor_dma_transfer(nor, from + i, host->dma_buffer, HIFMC_DMA_MAX_LEN, FMC_OP_READ); memcpy(read_buf + i, host->buffer, HIFMC_DMA_MAX_LEN); } /* read remaining bytes */ i -= HIFMC_DMA_MAX_LEN; hisi_spi_nor_dma_transfer(nor, from + i, host->dma_buffer, len - i, FMC_OP_READ); memcpy(read_buf + i, host->buffer, len - i); } *retlen = len; return 0; } > +static void hisi_spi_nor_write(struct spi_nor *nor, loff_t to, > + size_t len, size_t *retlen, const u_char *write_buf) > +{ > + struct hifmc_priv *priv = nor->priv; > + struct hifmc_host *host = priv->host; > + const unsigned char *ptr = write_buf; > + size_t actual_len; > + > + *retlen = 0; > + while (len > 0) { > + if (to & HIFMC_DMA_MASK) > + actual_len = (HIFMC_DMA_MAX_LEN - (to & HIFMC_DMA_MASK)) > + >= len ? len > + : (HIFMC_DMA_MAX_LEN - (to & HIFMC_DMA_MASK)); > + else > + actual_len = (len >= HIFMC_DMA_MAX_LEN) > + ? HIFMC_DMA_MAX_LEN : len; > + memcpy(host->buffer, ptr, actual_len); > + hisi_spi_nor_dma_transfer(nor, to, host->dma_buffer, actual_len, > + FMC_OP_WRITE); > + to += actual_len; > + ptr += actual_len; > + len -= actual_len; > + *retlen += actual_len; > + } > +} > + Because "len" passed from spi_nor_write is smaller than nor->page_size, and nor->page_size is smaller than the length of host->dma_buffer. We can transfer "len" bytes data by hisi_spi_nor_dma_transfer at one time. hisi_spi_nor_write can be simplified like below: static void hisi_spi_nor_write(struct spi_nor *nor, loff_t to, size_t len, size_t *retlen, const u_char *write_buf) { struct hifmc_priv *priv = nor->priv; struct hifmc_host *host = priv->host; /* len is smaller than dma buffer length*/ memcpy(host->buffer, write_buf, len); hisi_spi_nor_dma_transfer(nor, to, host->dma_buffer, len, FMC_OP_WRITE); *retlen = len; } Regards, Jiancheng