From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752371AbbKYTVg (ORCPT ); Wed, 25 Nov 2015 14:21:36 -0500 Received: from mail-bl2on0113.outbound.protection.outlook.com ([65.55.169.113]:65344 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751198AbbKYTVU (ORCPT ); Wed, 25 Nov 2015 14:21:20 -0500 Authentication-Results: spf=permerror (sender IP is 192.88.168.50) smtp.mailfrom=freescale.com; lists.infradead.org; dkim=none (message not signed) header.d=none;lists.infradead.org; dmarc=none action=none header.from=freescale.com; Date: Wed, 25 Nov 2015 13:09:01 -0600 From: Han Xu To: Yuan Yao CC: , , , Subject: Re: [PATCH v2] mtd: spi-nor: fsl-quadspi: add big-endian support Message-ID: <20151125190900.GA2959@chopperman.am.freescale.net> References: <1447838008-3744-1-git-send-email-yao.yuan@freescale.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <1447838008-3744-1-git-send-email-yao.yuan@freescale.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;BN1BFFO11FD055;1:dUUNeIevaf3qal6lU3QJ/vu7mkpmDLiIVvN7z/z1bdFSNCA4Dd+fyWfJpanyoHhBkAAcbsFK5QhbQt9BOciABGZYaT7EY/euEUPGR0RqJ/+VgrTt0qqQun7dXQieV50Kw+4egLBPDSG66cnHtDcTpDn/nsVTTlhqbslIaadIMGjalHe6kxWUvHX8aoZLUP4UPhBRfmwLfDzjMWFw+P4ytH7/f1R0sgpAx+xdnfLh4Vs7aAHKSg0fW5sTwi62wN6t89emTqbG0t2mByjaEpsVaaIocQwnxvBZEwljEaOcgC1JONqiwVjIZIgmL59FFoQRL68YIrLRBe9HDGM0mXDaooD5SeHeICI17KGv1VtdkMcaHr0+mJKRb3Mrp1njlv07QIcQ6M1UfV0PdJT4mZmqdcn4cjwSXbk5pmpoKy7deVk= X-Forefront-Antispam-Report: CIP:192.88.168.50;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10019020)(979002)(6009001)(2980300002)(448002)(199003)(24454002)(479174004)(189002)(104016004)(76176999)(19580405001)(50466002)(23726003)(11100500001)(81156007)(85326001)(97736004)(5007970100001)(4001350100001)(5001960100002)(46406003)(77096005)(586003)(83506001)(1076002)(87936001)(6806005)(5008740100001)(2950100001)(106466001)(92566002)(47776003)(19580395003)(5003600100002)(54356999)(86362001)(33656002)(50986999)(4001450100002)(189998001)(110136002)(97756001)(575784001)(1220700001)(969003)(989001)(999001)(1009001)(1019001);DIR:OUT;SFP:1102;SCL:1;SRVR:BY2PR03MB142;H:tx30smr01.am.freescale.net;FPR:;SPF:PermError;PTR:InfoDomainNonexistent;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB142;2:u1ijZwjbOQ/WmQMAcQqA8sAlpu+3vd6Qu5+jsfe4GXQTyW97GhoF2DYLgwDsYQooxs1uCH+7/uE9F4+wESzv6hI3eFRPx2DVS/M07MqPRrazO0trGULOJkcQ7w/7c/UYq8TRGGTS2+PCfxfPK7/MAoUAdxN/pbErRMpmQpB/zd4=;3:GnUOPDTVMlCp4EcwfPy6mCh1g/N9NTYLnjQVsAocjFiX+cfWNQFGYqtDqjug2ZncTNPcr4WvIkFBu4tgSs4vSfmx7wlh4ypMltLAnKvzlWX9b25QsjvydqXRuwzoCWgFtko1773iNxEeCcA+ZvAjsG3IN45gZavwrcnN6KWVfDoFyPmvUsl2a+zfqL8EdceyRWCEKCyokKaYOT4x3c4r0AgRFcJFru1UozxX+gOC/3o=;25:j112MdDW9bh79qGrCedzL11lxBCZtp0ghAWVJh3tDA3LNM+8zL4OHshq+JGGF2YTWM7v3EDDzYKuOTqSQQqR43fSdG6hn9CiMP31wMpho9qDkcpiQJz+55fZMyfy1j2cmuazud98mh9w48FkKPlwZJtXkIJY3TL1/6/wr/Pf2vN2Psc/1b4QTB5W54x3dRN4zUNhJwYbRWUXWfkU4C4CxcBRp2bVeapEPVEwLll5xPGy/47AsNGfoM3meiGQbLNEmC/EqDNlVEutEnzh2JpPBQ== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY2PR03MB142; X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB142;20:oFrvuq2hxYQSc4ZhjCMBZvJRc310rZZnXkDBc7lnfjcWNNhgCdhm+NcWc3HflxyICFXZipipvzOqF5JzYSxQpWJNvHtVWUn+29KhEd4OCvE1BSAF1I6h4T4RumQFY2nCxeEyhljnxUT1mQA/YK3T8tcTy1pUEy1UkU1X7qLLftQ7thuJdeaPTiTmaFc/fgP4IYezdLaUvGzWaScLX2hdzJjwNB9iOJ4EZZTouqLAGMm+HFVFMnUw8+dDfp8FhLjCR0CL80v2I1+zT+PMAgviw8u8QTdUb9WQ+T3Rdvh3svdSkvsnmlpBho3+AT1obbW7iYx55maG1s069gzchicFrDQ5OpF/MbwvfHKc/Bk9RKk=;4:9Znpm91q7cufWsgF5VL/hnlxvPfQmlqhgCs8hmmIDTayVXh5hqt3JEUDTMGzQOcZWA1DnvYnMOGtU2ugJXWn8wPcnMuzX34pjvqr0Q5tsC9ELe+r3TH/26mGbqMUAMVuVmbIT3p3lOqRt0c+OJ/YSvLrZEpZ8u0UkFotwdyI6K2b9dbn7JdojPx+dw5PHLHwZB4wOc08WVilayK7PvgqniTUrkvoA/BovXPhxzmFPA7gXwX+jyjYBV6IXAGfRWa7LnNMSi0Ac5jrF4PoUb1MCLLGbfSTBZB3BlBCHu7RPLZJgXpm+rE7kd3uZqLaeSc/cZYn4/5fmzhSIDSlpf/f2xOTJ+M6Lzy9Kn7M9TWvzfKAh6v9841WLx0OaRk/DHKi X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(101931422205132); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(5005006)(520078)(10201501046)(3002001);SRVR:BY2PR03MB142;BCL:0;PCL:0;RULEID:;SRVR:BY2PR03MB142; X-Forefront-PRVS: 0771670921 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BY2PR03MB142;23:l7haLa9iKZdQK9hl/TE9p/hg+2AqyKE4jc0XV/M9jp?= =?us-ascii?Q?4HZLeiiuuOd1uD8E02kPgbJx2Lb2WiRwDdDPYhRA/HzDvaL0BIRzUZtkgClV?= =?us-ascii?Q?1mJh3Bj5LbxbEM+XJVH3itYXHbbDc329+07i4KUbTx/J8CQjoTTEHodOqkgX?= =?us-ascii?Q?zwZOtHx+3+7711fiYQbe5G1iA7ycIeqa0Aqh/ZNdtHhJX7mXoCnLfb0CZSU+?= =?us-ascii?Q?p/HAQo36Nh2ZB3Khy1N3E6VeSMum6Zd2d0noQe6yOgJ7QbdvR+yPq9vUCahh?= =?us-ascii?Q?8wz4RCB0w5sqwylX1hm7kbidXzTPJCUQCPJL+Is8NSPxluvk0aYTMvEIhNnY?= =?us-ascii?Q?+CEBGLL+JhKjb1O72iG95ZGOstC5eeFS3J5eZ658njDJKT9B97W/3Dzh+POM?= =?us-ascii?Q?NCno/xlKJHf8tw5CQNzuBFjILc+i9Frj6YJFZKi5fsTPKyEcSF/6WPUWLYQy?= =?us-ascii?Q?ciyT+N6A1bQ5zLlqkemD3O9IIVbErqNROF00xomwaNKLeWC5W/O6MWO1arQm?= =?us-ascii?Q?ZitUDcg0BCb0Oj542z++QQzO916kNuHmk661R0BTOPOgouyrLTPGxx1b03/L?= =?us-ascii?Q?Z7jYVpDDh2m34TZmdTdDpl+jwat9o6yWJHxgARKgimFRaUmeF3EAToyF4yPf?= =?us-ascii?Q?Y1pbt7WMxZhU9U39NacShf7xAYppktDj/w1wtPOwQATwAZcxY+3oEk30Tk5L?= =?us-ascii?Q?ptRE0+Kf53BZa/BqegzI9yOXNmMFB+LVxIl+2OEIBjivWCfD6ZAadcK8439u?= =?us-ascii?Q?MsP+rW12FVr6phuTQe2PHck9cOPL2QKXPiXsdl+AEtqcC2RsTFg7CnqQ2k46?= =?us-ascii?Q?rU1NDYWmUP2VUvnSkiYg8Yx+zmQR2x3fFfmrnpMAECPpTQwRSdWPI5Rvv+76?= =?us-ascii?Q?z0JEhQ36q9IkVa4QqiCrVSJW9Et8MLcR0LMheWkVM+TU24bMkd8M56c4ENgd?= =?us-ascii?Q?TE/e8ImT5MveW2Eccsn8EQl45YTikHN1EuxGqUL3Sb92zI+Hu1R2zTCIGA4k?= =?us-ascii?Q?qiKVorV4Wfs7tig96WLNtVdHJ2TlItRCNxiMfdDIN/rD+aGSYpANkdD90/hh?= =?us-ascii?Q?JqUHYbt0KTQGzUIOuHBcEWwWTpUDk3Oqi0kLA+zI4KJRghiz4VRs7uF5Xp8r?= =?us-ascii?Q?MLHsUrzOfVVQVqx/rM9n+QUUAR2vmybikUFSNTfGgpI4LKwAQpfLKZNzcpav?= =?us-ascii?Q?SjvoJ3YDPWE1TK9j1u3X0Sj+iaPwukXCafK7GiaaeNl8rGHfyCmDGZMPTQkg?= =?us-ascii?Q?2NAEAeRislIQFVthjz8SbHXoigLsueqDHTIled?= X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB142;5:K8sra6TRzwmCutfNansV6dVQRIZD2vPoQpIOGOJ36zDmexCOaFS6XOwyb6PrKrTB9cGD01f1oy+EdeKODhXvCV3gteDet3eD9Lz0oEUwUk7aIb0wvMrVWp0Rrz8MyhuvrQ6e/nEbnKzI2QToBQbt1w==;24:Z88B9wlLkSSvnVjYwNtXfFSXxDajBfyr6PS4qMC3gv23+HlWc84ruNQaZiwUoDphea3WRbj5NxTdXJ5q2aBQOT6tuvoipAJWT9zgC2YHFls=;20:gTYKY+TP2heu0fsXAjxx5uraCDUPNDEFluNjSaz7kV8aSv4TbU4LH7DIXmg5OgWAp8IaGf+dPy0khmbOCCMkmQ== X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Nov 2015 19:21:14.9841 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d;Ip=[192.88.168.50];Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR03MB142 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Nov 18, 2015 at 05:13:28PM +0800, Yuan Yao wrote: > Add R/W functions for big- or little-endian registers: > The qSPI controller's endian is independent of the CPU core's endian. > So far, the qSPI have two versions for big-endian and little-endian. > > Signed-off-by: Yuan Yao > --- > Changed in v2: > Rebase to the lastest code. > --- > drivers/mtd/spi-nor/fsl-quadspi.c | 157 +++++++++++++++++++++++--------------- > 1 file changed, 97 insertions(+), 60 deletions(-) > > diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c > index 9e7f657..0ce7768 100644 > --- a/drivers/mtd/spi-nor/fsl-quadspi.c > +++ b/drivers/mtd/spi-nor/fsl-quadspi.c > @@ -275,6 +275,7 @@ struct fsl_qspi { > u32 clk_rate; > unsigned int chip_base_addr; /* We may support two chips. */ > bool has_second_chip; > + bool big_endian; > struct mutex lock; > struct pm_qos_request pm_qos_req; > }; > @@ -300,6 +301,28 @@ static inline int needs_wakeup_wait_mode(struct fsl_qspi *q) > } > > /* > + * R/W functions for big- or little-endian registers: > + * The qSPI controller's endian is independent of the CPU core's endian. > + * So far, although the CPU core is little-endian but the qSPI have two > + * versions for big-endian and little-endian. > + */ > +static void qspi_writel(struct fsl_qspi *q, u32 val, void __iomem *addr) > +{ > + if (q->big_endian) > + iowrite32be(val, addr); > + else > + iowrite32(val, addr); > +} > + > +static u32 qspi_readl(struct fsl_qspi *q, void __iomem *addr) > +{ > + if (q->big_endian) > + return ioread32be(addr); > + else > + return ioread32(addr); > +} > + > +/* > * An IC bug makes us to re-arrange the 32-bit data. > * The following chips, such as IMX6SLX, have fixed this bug. > */ > @@ -310,14 +333,14 @@ static inline u32 fsl_qspi_endian_xchg(struct fsl_qspi *q, u32 a) > > static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q) > { > - writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); > - writel(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR); > + qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); > + qspi_writel(q, QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR); > } > > static inline void fsl_qspi_lock_lut(struct fsl_qspi *q) > { > - writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); > - writel(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR); > + qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); > + qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR); > } > > static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id) > @@ -326,8 +349,8 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id) > u32 reg; > > /* clear interrupt */ > - reg = readl(q->iobase + QUADSPI_FR); > - writel(reg, q->iobase + QUADSPI_FR); > + reg = qspi_readl(q, q->iobase + QUADSPI_FR); > + qspi_writel(q, reg, q->iobase + QUADSPI_FR); > > if (reg & QUADSPI_FR_TFF_MASK) > complete(&q->c); > @@ -348,7 +371,7 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) > > /* Clear all the LUT table */ > for (i = 0; i < QUADSPI_LUT_NUM; i++) > - writel(0, base + QUADSPI_LUT_BASE + i * 4); > + qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4); > > /* Quad Read */ > lut_base = SEQID_QUAD_READ * 4; > @@ -364,14 +387,15 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) > dummy = 8; > } > > - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), > + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), > base + QUADSPI_LUT(lut_base)); > - writel(LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo), > + qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo), > base + QUADSPI_LUT(lut_base + 1)); > > /* Write enable */ > lut_base = SEQID_WREN * 4; > - writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base)); > + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN), > + base + QUADSPI_LUT(lut_base)); > > /* Page Program */ > lut_base = SEQID_PP * 4; > @@ -385,13 +409,15 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) > addrlen = ADDR32BIT; > } > > - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), > + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), > base + QUADSPI_LUT(lut_base)); > - writel(LUT0(FSL_WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1)); > + qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0), > + base + QUADSPI_LUT(lut_base + 1)); > > /* Read Status */ > lut_base = SEQID_RDSR * 4; > - writel(LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(FSL_READ, PAD1, 0x1), > + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) | > + LUT1(FSL_READ, PAD1, 0x1), > base + QUADSPI_LUT(lut_base)); > > /* Erase a sector */ > @@ -400,40 +426,46 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) > cmd = q->nor[0].erase_opcode; > addrlen = q->nor_size <= SZ_16M ? ADDR24BIT : ADDR32BIT; > > - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), > + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), > base + QUADSPI_LUT(lut_base)); > > /* Erase the whole chip */ > lut_base = SEQID_CHIP_ERASE * 4; > - writel(LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE), > + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE), > base + QUADSPI_LUT(lut_base)); > > /* READ ID */ > lut_base = SEQID_RDID * 4; > - writel(LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(FSL_READ, PAD1, 0x8), > + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) | > + LUT1(FSL_READ, PAD1, 0x8), > base + QUADSPI_LUT(lut_base)); > > /* Write Register */ > lut_base = SEQID_WRSR * 4; > - writel(LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(FSL_WRITE, PAD1, 0x2), > + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) | > + LUT1(FSL_WRITE, PAD1, 0x2), > base + QUADSPI_LUT(lut_base)); > > /* Read Configuration Register */ > lut_base = SEQID_RDCR * 4; > - writel(LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(FSL_READ, PAD1, 0x1), > + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) | > + LUT1(FSL_READ, PAD1, 0x1), > base + QUADSPI_LUT(lut_base)); > > /* Write disable */ > lut_base = SEQID_WRDI * 4; > - writel(LUT0(CMD, PAD1, SPINOR_OP_WRDI), base + QUADSPI_LUT(lut_base)); > + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI), > + base + QUADSPI_LUT(lut_base)); > > /* Enter 4 Byte Mode (Micron) */ > lut_base = SEQID_EN4B * 4; > - writel(LUT0(CMD, PAD1, SPINOR_OP_EN4B), base + QUADSPI_LUT(lut_base)); > + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B), > + base + QUADSPI_LUT(lut_base)); > > /* Enter 4 Byte Mode (Spansion) */ > lut_base = SEQID_BRWR * 4; > - writel(LUT0(CMD, PAD1, SPINOR_OP_BRWR), base + QUADSPI_LUT(lut_base)); > + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR), > + base + QUADSPI_LUT(lut_base)); > > fsl_qspi_lock_lut(q); > } > @@ -488,15 +520,16 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len) > q->chip_base_addr, addr, len, cmd); > > /* save the reg */ > - reg = readl(base + QUADSPI_MCR); > + reg = qspi_readl(q, base + QUADSPI_MCR); > > - writel(q->memmap_phy + q->chip_base_addr + addr, base + QUADSPI_SFAR); > - writel(QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS, > + qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr, > + base + QUADSPI_SFAR); > + qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS, > base + QUADSPI_RBCT); > - writel(reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR); > + qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR); > > do { > - reg2 = readl(base + QUADSPI_SR); > + reg2 = qspi_readl(q, base + QUADSPI_SR); > if (reg2 & (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK)) { > udelay(1); > dev_dbg(q->dev, "The controller is busy, 0x%x\n", reg2); > @@ -507,21 +540,22 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len) > > /* trigger the LUT now */ > seqid = fsl_qspi_get_seqid(q, cmd); > - writel((seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, base + QUADSPI_IPCR); > + qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, > + base + QUADSPI_IPCR); > > /* Wait for the interrupt. */ > if (!wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000))) { > dev_err(q->dev, > "cmd 0x%.2x timeout, addr@%.8x, FR:0x%.8x, SR:0x%.8x\n", > - cmd, addr, readl(base + QUADSPI_FR), > - readl(base + QUADSPI_SR)); > + cmd, addr, qspi_readl(q, base + QUADSPI_FR), > + qspi_readl(q, base + QUADSPI_SR)); > err = -ETIMEDOUT; > } else { > err = 0; > } > > /* restore the MCR */ > - writel(reg, base + QUADSPI_MCR); > + qspi_writel(q, reg, base + QUADSPI_MCR); > > return err; > } > @@ -533,7 +567,7 @@ static void fsl_qspi_read_data(struct fsl_qspi *q, int len, u8 *rxbuf) > int i = 0; > > while (len > 0) { > - tmp = readl(q->iobase + QUADSPI_RBDR + i * 4); > + tmp = qspi_readl(q, q->iobase + QUADSPI_RBDR + i * 4); > tmp = fsl_qspi_endian_xchg(q, tmp); > dev_dbg(q->dev, "chip addr:0x%.8x, rcv:0x%.8x\n", > q->chip_base_addr, tmp); > @@ -561,9 +595,9 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q) > { > u32 reg; > > - reg = readl(q->iobase + QUADSPI_MCR); > + reg = qspi_readl(q, q->iobase + QUADSPI_MCR); > reg |= QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK; > - writel(reg, q->iobase + QUADSPI_MCR); > + qspi_writel(q, reg, q->iobase + QUADSPI_MCR); > > /* > * The minimum delay : 1 AHB + 2 SFCK clocks. > @@ -572,7 +606,7 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q) > udelay(1); > > reg &= ~(QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK); > - writel(reg, q->iobase + QUADSPI_MCR); > + qspi_writel(q, reg, q->iobase + QUADSPI_MCR); > } > > static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor, > @@ -586,20 +620,20 @@ static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor, > q->chip_base_addr, to, count); > > /* clear the TX FIFO. */ > - tmp = readl(q->iobase + QUADSPI_MCR); > - writel(tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR); > + tmp = qspi_readl(q, q->iobase + QUADSPI_MCR); > + qspi_writel(q, tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR); > > /* fill the TX data to the FIFO */ > for (j = 0, i = ((count + 3) / 4); j < i; j++) { > tmp = fsl_qspi_endian_xchg(q, *txbuf); > - writel(tmp, q->iobase + QUADSPI_TBDR); > + qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR); > txbuf++; > } > > /* fill the TXFIFO upto 16 bytes for i.MX7d */ > if (needs_fill_txfifo(q)) > for (; i < 4; i++) > - writel(tmp, q->iobase + QUADSPI_TBDR); > + qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR); > > /* Trigger it */ > ret = fsl_qspi_runcmd(q, opcode, to, count); > @@ -615,10 +649,10 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q) > int nor_size = q->nor_size; > void __iomem *base = q->iobase; > > - writel(nor_size + q->memmap_phy, base + QUADSPI_SFA1AD); > - writel(nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD); > - writel(nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD); > - writel(nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD); > + qspi_writel(q, nor_size + q->memmap_phy, base + QUADSPI_SFA1AD); > + qspi_writel(q, nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD); > + qspi_writel(q, nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD); > + qspi_writel(q, nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD); > } > > /* > @@ -640,24 +674,26 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q) > int seqid; > > /* AHB configuration for access buffer 0/1/2 .*/ > - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR); > - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR); > - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR); > + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR); > + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR); > + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR); > /* > * Set ADATSZ with the maximum AHB buffer size to improve the > * read performance. > */ > - writel(QUADSPI_BUF3CR_ALLMST_MASK | ((q->devtype_data->ahb_buf_size / 8) > - << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR); > + qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK | > + ((q->devtype_data->ahb_buf_size / 8) > + << QUADSPI_BUF3CR_ADATSZ_SHIFT), > + base + QUADSPI_BUF3CR); > > /* We only use the buffer3 */ > - writel(0, base + QUADSPI_BUF0IND); > - writel(0, base + QUADSPI_BUF1IND); > - writel(0, base + QUADSPI_BUF2IND); > + qspi_writel(q, 0, base + QUADSPI_BUF0IND); > + qspi_writel(q, 0, base + QUADSPI_BUF1IND); > + qspi_writel(q, 0, base + QUADSPI_BUF2IND); > > /* Set the default lut sequence for AHB Read. */ > seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode); > - writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT, > + qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT, > q->iobase + QUADSPI_BFGENCR); > } > > @@ -713,7 +749,7 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q) > return ret; > > /* Reset the module */ > - writel(QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK, > + qspi_writel(q, QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK, > base + QUADSPI_MCR); > udelay(1); > > @@ -721,24 +757,24 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q) > fsl_qspi_init_lut(q); > > /* Disable the module */ > - writel(QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK, > + qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK, > base + QUADSPI_MCR); > > - reg = readl(base + QUADSPI_SMPR); > - writel(reg & ~(QUADSPI_SMPR_FSDLY_MASK > + reg = qspi_readl(q, base + QUADSPI_SMPR); > + qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK > | QUADSPI_SMPR_FSPHS_MASK > | QUADSPI_SMPR_HSENA_MASK > | QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR); > > /* Enable the module */ > - writel(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK, > + qspi_writel(q, QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK, > base + QUADSPI_MCR); > > /* clear all interrupt status */ > - writel(0xffffffff, q->iobase + QUADSPI_FR); > + qspi_writel(q, 0xffffffff, q->iobase + QUADSPI_FR); > > /* enable the interrupt */ > - writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER); > + qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER); > > return 0; > } > @@ -954,6 +990,7 @@ static int fsl_qspi_probe(struct platform_device *pdev) > if (IS_ERR(q->iobase)) > return PTR_ERR(q->iobase); > > + q->big_endian = of_property_read_bool(np, "big-endian"); I am fine with this patch, but need document the new property with another patch > res = platform_get_resource_byname(pdev, IORESOURCE_MEM, > "QuadSPI-memory"); > if (!devm_request_mem_region(dev, res->start, resource_size(res), > @@ -1101,8 +1138,8 @@ static int fsl_qspi_remove(struct platform_device *pdev) > } > > /* disable the hardware */ > - writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR); > - writel(0x0, q->iobase + QUADSPI_RSER); > + qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR); > + qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER); > > mutex_destroy(&q->lock); > > -- > 2.1.0.27.g96db324 > Acked-by: Han xu -- Best Regards, Han "Allen" Xu