-static int rb4xx_spi_read_fast(struct rb4xx_spi *rbspi,
- struct spi_message *m)
-{
- struct spi_transfer *t;
- const unsigned char *tx_ptr;
- unsigned addr;
- void __iomem *base = rbspi->base;
-
- /* check for exactly two transfers */
- if (list_empty(&m->transfers) ||
- list_is_last(m->transfers.next, &m->transfers) ||
- !list_is_last(m->transfers.next->next, &m->transfers)) {
- return -1;
- }
-
- /* first transfer contains command and address */
- t = list_entry(m->transfers.next,
- struct spi_transfer, transfer_list);
-
- if (t->len != 5 || t->tx_buf == NULL)
- return -1;
-
- tx_ptr = t->tx_buf;
- if (tx_ptr[0] != CPLD_CMD_READ_FAST)
- return -1;
-
- addr = tx_ptr[1];
- addr = tx_ptr[2] | (addr << 8);
- addr = tx_ptr[3] | (addr << 8);
- addr += (unsigned) base;
-
- m->actual_length += t->len;
-
- /* second transfer contains data itself */
- t = list_entry(m->transfers.next->next,
- struct spi_transfer, transfer_list);
-
- if (t->tx_buf && !t->verify)
- return -1;
-
- __raw_writel(AR71XX_SPI_FS_GPIO, base + AR71XX_SPI_REG_FS);
- __raw_writel(rbspi->spi_ctrl_fread, base + AR71XX_SPI_REG_CTRL);
- __raw_writel(0, base + AR71XX_SPI_REG_FS);
-
- if (t->rx_buf) {
- memcpy(t->rx_buf, (const void *)addr, t->len);
- } else if (t->tx_buf) {
- unsigned char buf[t->len];
- memcpy(buf, (const void *)addr, t->len);
- if (memcmp(t->tx_buf, buf, t->len) != 0)
- m->status = -EMSGSIZE;
- }
- m->actual_length += t->len;
-
- if (rbspi->spi_ctrl_flash != rbspi->spi_ctrl_fread) {
- __raw_writel(AR71XX_SPI_FS_GPIO, base + AR71XX_SPI_REG_FS);
- __raw_writel(rbspi->spi_ctrl_flash, base + AR71XX_SPI_REG_CTRL);
- __raw_writel(0, base + AR71XX_SPI_REG_FS);
- }
-
- return 0;
-}
-