All of lore.kernel.org
 help / color / mirror / Atom feed
From: Han Xu <xhnjupt@gmail.com>
To: Yuan Yao <yao.yuan@freescale.com>
Cc: dwmw2@infradead.org, computersforpeace@gmail.com,
	han.xu@freescale.com, robh@kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-mtd@lists.infradead.org, yao.yuan@nxp.com,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v4 1/7] mtd: spi-nor: fsl-quadspi: add big-endian support
Date: Thu, 18 Feb 2016 01:13:08 +0800	[thread overview]
Message-ID: <20160217171308.GB16812@shlinux2> (raw)
In-Reply-To: <1453793041-35868-1-git-send-email-yao.yuan@freescale.com>

On Tue, Jan 26, 2016 at 03:23:55PM +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 <yao.yuan@nxp.com>
> Acked-by: Han xu <han.xu@freescale.com>
> ---
> Changed in v4:
> No changes.
> 
> Changed in v3:
> Update my email to <yao.yuan@nxp.com>
> 
> 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 54640f1..04e8a93 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");
>  	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 <han.xu@nxp.com>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/

WARNING: multiple messages have this Message-ID (diff)
From: xhnjupt@gmail.com (Han Xu)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 1/7] mtd: spi-nor: fsl-quadspi: add big-endian support
Date: Thu, 18 Feb 2016 01:13:08 +0800	[thread overview]
Message-ID: <20160217171308.GB16812@shlinux2> (raw)
In-Reply-To: <1453793041-35868-1-git-send-email-yao.yuan@freescale.com>

On Tue, Jan 26, 2016 at 03:23:55PM +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 <yao.yuan@nxp.com>
> Acked-by: Han xu <han.xu@freescale.com>
> ---
> Changed in v4:
> No changes.
> 
> Changed in v3:
> Update my email to <yao.yuan@nxp.com>
> 
> 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 54640f1..04e8a93 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");
>  	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 <han.xu@nxp.com>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/

WARNING: multiple messages have this Message-ID (diff)
From: Han Xu <xhnjupt-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: Yuan Yao <yao.yuan-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
Cc: dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org,
	computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	han.xu-KZfg59tc24xl57MIdRCFDg@public.gmane.org,
	robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	yao.yuan-3arQi8VN3Tc@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Subject: Re: [PATCH v4 1/7] mtd: spi-nor: fsl-quadspi: add big-endian support
Date: Thu, 18 Feb 2016 01:13:08 +0800	[thread overview]
Message-ID: <20160217171308.GB16812@shlinux2> (raw)
In-Reply-To: <1453793041-35868-1-git-send-email-yao.yuan-KZfg59tc24xl57MIdRCFDg@public.gmane.org>

On Tue, Jan 26, 2016 at 03:23:55PM +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 <yao.yuan-3arQi8VN3Tc@public.gmane.org>
> Acked-by: Han xu <han.xu-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
> ---
> Changed in v4:
> No changes.
> 
> Changed in v3:
> Update my email to <yao.yuan-3arQi8VN3Tc@public.gmane.org>
> 
> 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 54640f1..04e8a93 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");
>  	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 <han.xu-3arQi8VN3Tc@public.gmane.org>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2016-02-17 17:13 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-26  7:23 [PATCH v4 1/7] mtd: spi-nor: fsl-quadspi: add big-endian support Yuan Yao
2016-01-26  7:23 ` Yuan Yao
2016-01-26  7:23 ` Yuan Yao
2016-01-26  7:23 ` [PATCH v4 2/7] mtd: spi-nor: fsl-quadspi: add support for ls1021a Yuan Yao
2016-01-26  7:23   ` Yuan Yao
2016-01-26  7:23   ` Yuan Yao
2016-02-17 17:14   ` Han Xu
2016-02-17 17:14     ` Han Xu
2016-01-26  7:23 ` [PATCH v4 3/7] mtd: spi-nor: fsl-quadspi: add support for layerscape Yuan Yao
2016-01-26  7:23   ` Yuan Yao
2016-01-26  7:23   ` Yuan Yao
2016-02-17 17:15   ` Han Xu
2016-02-17 17:15     ` Han Xu
2016-01-26  7:23 ` [PATCH v4 4/7] Documentation: fsl-quadspi: Add fsl, ls2080a-dspi compatible string Yuan Yao
2016-01-26  7:23   ` [PATCH v4 4/7] Documentation: fsl-quadspi: Add fsl,ls2080a-dspi " Yuan Yao
2016-01-26  7:23   ` Yuan Yao
2016-01-26  7:23   ` [PATCH v4 4/7] Documentation: fsl-quadspi: Add fsl, ls2080a-dspi " Yuan Yao
2016-02-17 17:15   ` Han Xu
2016-02-17 17:15     ` Han Xu
2016-03-07 20:32   ` [PATCH v4 4/7] Documentation: fsl-quadspi: Add fsl,ls2080a-dspi " Brian Norris
2016-03-07 20:32     ` Brian Norris
2016-03-07 20:32     ` Brian Norris
2016-03-08  2:03     ` Yao Yuan
2016-03-08  2:03       ` Yao Yuan
2016-03-08  2:03       ` Yao Yuan
2016-01-26  7:23 ` [PATCH v4 5/7] Documentation: fsl-quadspi: Add fsl, ls2080a-qspi " Yuan Yao
2016-01-26  7:23   ` Yuan Yao
2016-01-26  7:23   ` Yuan Yao
2016-02-17 17:15   ` Han Xu
2016-02-17 17:15     ` Han Xu
2016-01-26  7:24 ` [PATCH v4 6/7] dts/ls2080a: update the DTS for QSPI and DSPI support Yuan Yao
2016-01-26  7:24   ` Yuan Yao
2016-01-26  7:24   ` Yuan Yao
2016-02-17 17:16   ` Han Xu
2016-02-17 17:16     ` Han Xu
2016-01-26  7:24 ` [PATCH v4 7/7] Documentation: fsl-quadspi: Add optional properties Yuan Yao
2016-01-26  7:24   ` Yuan Yao
2016-01-26  7:24   ` Yuan Yao
2016-02-17 17:16   ` Han Xu
2016-02-17 17:16     ` Han Xu
2016-02-17 17:13 ` Han Xu [this message]
2016-02-17 17:13   ` [PATCH v4 1/7] mtd: spi-nor: fsl-quadspi: add big-endian support Han Xu
2016-02-17 17:13   ` Han Xu
2016-03-07 20:34 ` Brian Norris
2016-03-07 20:34   ` Brian Norris
2016-03-07 20:34   ` Brian Norris

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160217171308.GB16812@shlinux2 \
    --to=xhnjupt@gmail.com \
    --cc=computersforpeace@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dwmw2@infradead.org \
    --cc=han.xu@freescale.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=robh@kernel.org \
    --cc=yao.yuan@freescale.com \
    --cc=yao.yuan@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.