else
                                txw = *(u16 *)(dws->tx);
                }
-               dw_writel(dws, DW_SPI_DR, txw);
+               dw_write_io_reg(dws, DW_SPI_DR, txw);
                dws->tx += dws->n_bytes;
        }
 }
        u16 rxw;
 
        while (max--) {
-               rxw = dw_readl(dws, DW_SPI_DR);
+               rxw = dw_read_io_reg(dws, DW_SPI_DR);
                /* Care rx only if the transfer's original "rx" is not null */
                if (dws->rx_end - dws->len) {
                        if (dws->n_bytes == 1)
 
        u32                     fifo_len;       /* depth of the FIFO buffer */
        u32                     max_freq;       /* max bus freq supported */
 
+       u32                     reg_io_width;   /* DR I/O width in bytes */
        u16                     bus_num;
        u16                     num_cs;         /* supported slave numbers */
 
        return __raw_readl(dws->regs + offset);
 }
 
+static inline u16 dw_readw(struct dw_spi *dws, u32 offset)
+{
+       return __raw_readw(dws->regs + offset);
+}
+
 static inline void dw_writel(struct dw_spi *dws, u32 offset, u32 val)
 {
        __raw_writel(val, dws->regs + offset);
 }
 
+static inline void dw_writew(struct dw_spi *dws, u32 offset, u16 val)
+{
+       __raw_writew(val, dws->regs + offset);
+}
+
+static inline u32 dw_read_io_reg(struct dw_spi *dws, u32 offset)
+{
+       switch (dws->reg_io_width) {
+       case 2:
+               return dw_readw(dws, offset);
+       case 4:
+       default:
+               return dw_readl(dws, offset);
+       }
+}
+
+static inline void dw_write_io_reg(struct dw_spi *dws, u32 offset, u32 val)
+{
+       switch (dws->reg_io_width) {
+       case 2:
+               dw_writew(dws, offset, val);
+               break;
+       case 4:
+       default:
+               dw_writel(dws, offset, val);
+               break;
+       }
+}
+
 static inline void spi_enable_chip(struct dw_spi *dws, int enable)
 {
        dw_writel(dws, DW_SPI_SSIENR, (enable ? 1 : 0));