From patchwork Wed Jun 8 10:18:04 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyungmin Park X-Patchwork-Id: 99396 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1AD84B6FFD for ; Wed, 8 Jun 2011 20:18:34 +1000 (EST) Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QUFqA-0007H0-VU; Wed, 08 Jun 2011 10:18:23 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QUFqA-0008O3-GR; Wed, 08 Jun 2011 10:18:22 +0000 Received: from mailout1.samsung.com ([203.254.224.24]) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QUFq7-0008Nk-9M for linux-mtd@lists.infradead.org; Wed, 08 Jun 2011 10:18:20 +0000 Received: from epcpsbgm2.samsung.com (mailout1.samsung.com [203.254.224.24]) by mailout1.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTP id <0LMG00JVZVAEN0P0@mailout1.samsung.com> for linux-mtd@lists.infradead.org; Wed, 08 Jun 2011 19:18:14 +0900 (KST) X-AuditID: cbfee61b-b7c62ae0000056ed-95-4def4c66e9e6 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (MMPCPMTA) with SMTP id B4.48.22253.66C4FED4; Wed, 08 Jun 2011 19:18:14 +0900 (KST) Received: from TNRNDGASPAPP1.tn.corp.samsungelectronics.net (unknown [165.213.149.150]) by mmp1.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTPA id <0LMG0054CVAEO670@mmp1.samsung.com> for linux-mtd@lists.infradead.org; Wed, 08 Jun 2011 19:18:14 +0900 (KST) Received: from july ([165.213.219.111]) by TNRNDGASPAPP1.tn.corp.samsungelectronics.net with Microsoft SMTPSVC(6.0.3790.4675); Wed, 08 Jun 2011 19:17:41 +0900 Received: by july (sSMTP sendmail emulation); Wed, 08 Jun 2011 19:18:04 +0900 Date: Wed, 08 Jun 2011 19:18:04 +0900 From: Kyungmin Park To: linux-mtd@lists.infradead.org Subject: [PATCH] mtd: OneNAND: samsung: Write DMA support Message-id: <20110608101804.GA5527@july> MIME-version: 1.0 Content-disposition: inline User-Agent: Mutt/1.5.17 (2007-11-01) X-OriginalArrivalTime: 08 Jun 2011 10:17:41.0474 (UTC) FILETIME=[4CD56420:01CC25C5] X-Brightmail-Tracker: AAAAAA== X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110608_061819_633747_AB34F4B3 X-CRM114-Status: GOOD ( 15.34 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [203.254.224.24 listed in list.dnswl.org] Cc: dwmw2@infradead.org, dedekind1@gmail.com X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Kyungmin Park Implement the write DMA feature. It can reduce the CPU usage when write. Signed-off-by: Kyungmin Park diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c index 3306b5b..f24cb6f 100644 --- a/drivers/mtd/onenand/samsung.c +++ b/drivers/mtd/onenand/samsung.c @@ -712,6 +712,74 @@ normal: return 0; } +static int s5pc110_write_bufferram(struct mtd_info *mtd, int area, + const unsigned char *buffer, int offset, size_t count) +{ + struct onenand_chip *this = mtd->priv; + struct device *dev = &onenand->pdev->dev; + void __iomem *p; + void *buf = (void *) buffer; + dma_addr_t dma_src, dma_dst; + int err, ofs, page_dma = 0; + + p = this->base + area; + if (ONENAND_CURRENT_BUFFERRAM(this)) { + if (area == ONENAND_DATARAM) + p += this->writesize; + else + p += mtd->oobsize; + } + + if (count != mtd->writesize || offset & 3 || (size_t) buf & 3) + goto normal; + + /* Handle vmalloc address */ + if (buf >= high_memory) { + struct page *page; + + if (((size_t) buf & PAGE_MASK) != + ((size_t) (buf + count - 1) & PAGE_MASK)) + goto normal; + + page = vmalloc_to_page(buf); + if (unlikely(!page)) + goto normal; + + /* Page offset */ + ofs = ((size_t) buf & ~PAGE_MASK); + page_dma = 1; + + /* DMA routine */ + dma_src = dma_map_page(dev, page, ofs, count, DMA_TO_DEVICE); + dma_dst = onenand->phys_base + (p - this->base); + } else { + /* DMA routine */ + dma_src = dma_map_single(dev, buf, count, DMA_TO_DEVICE); + dma_dst = onenand->phys_base + (p - this->base); + } + + if (dma_mapping_error(dev, dma_src)) { + dev_err(dev, "Couldn't map a %d byte buffer for DMA\n", count); + goto normal; + } + + err = s5pc110_dma_ops((void *) dma_dst, (void *) dma_src, + count, S5PC110_DMA_DIR_WRITE); + + if (page_dma) + dma_unmap_page(dev, dma_src, count, DMA_TO_DEVICE); + else + dma_unmap_single(dev, dma_src, count, DMA_TO_DEVICE); + + if (!err) + return 0; + +normal: + memcpy(p + offset, buffer, count); + + return 0; +} + static int s5pc110_chip_probe(struct mtd_info *mtd) { /* Now just return 0 */ @@ -844,6 +912,7 @@ static void s3c_onenand_setup(struct mtd_info *mtd) } else if (onenand->type == TYPE_S5PC110) { /* Use generic onenand functions */ this->read_bufferram = s5pc110_read_bufferram; + this->write_bufferram = s5pc110_write_bufferram; this->chip_probe = s5pc110_chip_probe; return; } else {