#define SEQID_RDEAR            11
 #define SEQID_WREAR            12
 #endif
+#define SEQID_WRAR             13
+#define SEQID_RDAR             14
 
 /* QSPI CMD */
 #define QSPI_CMD_PP            0x02    /* Page program (up to 256 bytes) */
 #define        QSPI_CMD_BRRD           0x16    /* Bank register read */
 #define        QSPI_CMD_BRWR           0x17    /* Bank register write */
 
+/* Used for Spansion S25FS-S family flash only. */
+#define QSPI_CMD_RDAR          0x65    /* Read any device register */
+#define QSPI_CMD_WRAR          0x71    /* Write any device register */
+
 /* 4-byte address QSPI CMD - used on Spansion and some Macronix flashes */
 #define QSPI_CMD_FAST_READ_4B  0x0c    /* Read data bytes (high frequency) */
 #define QSPI_CMD_PP_4B         0x12    /* Page program (up to 256 bytes) */
                     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
                     PAD1(LUT_PAD1) | INSTR1(LUT_WRITE));
 #endif
+
+       /*
+        * Read any device register.
+        * Used for Spansion S25FS-S family flash only.
+        */
+       lut_base = SEQID_RDAR * 4;
+       qspi_write32(priv->flags, ®s->lut[lut_base],
+                    OPRND0(QSPI_CMD_RDAR) | PAD0(LUT_PAD1) |
+                    INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
+                    PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
+       qspi_write32(priv->flags, ®s->lut[lut_base + 1],
+                    OPRND0(8) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) |
+                    OPRND1(1) | PAD1(LUT_PAD1) |
+                    INSTR1(LUT_READ));
+
+       /*
+        * Write any device register.
+        * Used for Spansion S25FS-S family flash only.
+        */
+       lut_base = SEQID_WRAR * 4;
+       qspi_write32(priv->flags, ®s->lut[lut_base],
+                    OPRND0(QSPI_CMD_WRAR) | PAD0(LUT_PAD1) |
+                    INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
+                    PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
+       qspi_write32(priv->flags, ®s->lut[lut_base + 1],
+                    OPRND0(1) | PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
+
        /* Lock the LUT */
        qspi_write32(priv->flags, ®s->lutkey, LUT_KEY_VALUE);
        qspi_write32(priv->flags, ®s->lckcr, QSPI_LCKCR_LOCK);
        qspi_write32(priv->flags, ®s->mcr, mcr_reg);
 }
 
-#ifndef CONFIG_SYS_FSL_QSPI_AHB
 /* If not use AHB read, read data from ip interface */
 static void qspi_op_read(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len)
 {
        u32 mcr_reg, data;
        int i, size;
        u32 to_or_from;
+       u32 seqid;
+
+       if (priv->cur_seqid == QSPI_CMD_RDAR)
+               seqid = SEQID_RDAR;
+       else
+               seqid = SEQID_FAST_READ;
 
        mcr_reg = qspi_read32(priv->flags, ®s->mcr);
        qspi_write32(priv->flags, ®s->mcr,
                        RX_BUFFER_SIZE : len;
 
                qspi_write32(priv->flags, ®s->ipcr,
-                            (SEQID_FAST_READ << QSPI_IPCR_SEQID_SHIFT) |
+                            (seqid << QSPI_IPCR_SEQID_SHIFT) |
                             size);
                while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK)
                        ;
                while ((RX_BUFFER_SIZE >= size) && (size > 0)) {
                        data = qspi_read32(priv->flags, ®s->rbdr[i]);
                        data = qspi_endian_xchg(data);
-                       memcpy(rxbuf, &data, 4);
+                       if (size < 4)
+                               memcpy(rxbuf, &data, size);
+                       else
+                               memcpy(rxbuf, &data, 4);
                        rxbuf++;
                        size -= 4;
                        i++;
 
        qspi_write32(priv->flags, ®s->mcr, mcr_reg);
 }
-#endif
 
 static void qspi_op_write(struct fsl_qspi_priv *priv, u8 *txbuf, u32 len)
 {
 
        /* Default is page programming */
        seqid = SEQID_PP;
+       if (priv->cur_seqid == QSPI_CMD_WRAR)
+               seqid = SEQID_WRAR;
 #ifdef CONFIG_SPI_FLASH_BAR
        if (priv->cur_seqid == QSPI_CMD_BRWR)
                seqid = SEQID_BRWR;
                        return 0;
                }
 
-               if (priv->cur_seqid == QSPI_CMD_FAST_READ) {
+               if (priv->cur_seqid == QSPI_CMD_FAST_READ ||
+                   priv->cur_seqid == QSPI_CMD_RDAR) {
                        priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
                } else if ((priv->cur_seqid == QSPI_CMD_SE) ||
                           (priv->cur_seqid == QSPI_CMD_BE_4K)) {
                        priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
                        qspi_op_erase(priv);
-               } else if (priv->cur_seqid == QSPI_CMD_PP) {
+               } else if (priv->cur_seqid == QSPI_CMD_PP ||
+                          priv->cur_seqid == QSPI_CMD_WRAR) {
                        wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK;
                } else if ((priv->cur_seqid == QSPI_CMD_BRWR) ||
                         (priv->cur_seqid == QSPI_CMD_WREAR)) {
 #else
                        qspi_op_read(priv, din, bytes);
 #endif
+               } else if (priv->cur_seqid == QSPI_CMD_RDAR) {
+                       qspi_op_read(priv, din, bytes);
                } else if (priv->cur_seqid == QSPI_CMD_RDID)
                        qspi_op_rdid(priv, din, bytes);
                else if (priv->cur_seqid == QSPI_CMD_RDSR)