diff options
| -rw-r--r-- | drivers/spi/spi-altera.c | 75 |
1 files changed, 35 insertions, 40 deletions
diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c index bfac34068999..a5adf0d868fc 100644 --- a/drivers/spi/spi-altera.c +++ b/drivers/spi/spi-altera.c | |||
| @@ -76,18 +76,43 @@ static void altera_spi_set_cs(struct spi_device *spi, bool is_high) | |||
| 76 | } | 76 | } |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | static inline unsigned int hw_txbyte(struct altera_spi *hw, int count) | 79 | static void altera_spi_tx_word(struct altera_spi *hw) |
| 80 | { | 80 | { |
| 81 | unsigned int txd = 0; | ||
| 82 | |||
| 81 | if (hw->tx) { | 83 | if (hw->tx) { |
| 82 | switch (hw->bytes_per_word) { | 84 | switch (hw->bytes_per_word) { |
| 83 | case 1: | 85 | case 1: |
| 84 | return hw->tx[count]; | 86 | txd = hw->tx[hw->count]; |
| 87 | break; | ||
| 85 | case 2: | 88 | case 2: |
| 86 | return (hw->tx[count * 2] | 89 | txd = (hw->tx[hw->count * 2] |
| 87 | | (hw->tx[count * 2 + 1] << 8)); | 90 | | (hw->tx[hw->count * 2 + 1] << 8)); |
| 91 | break; | ||
| 88 | } | 92 | } |
| 89 | } | 93 | } |
| 90 | return 0; | 94 | |
| 95 | writel(txd, hw->base + ALTERA_SPI_TXDATA); | ||
| 96 | } | ||
| 97 | |||
| 98 | static void altera_spi_rx_word(struct altera_spi *hw) | ||
| 99 | { | ||
| 100 | unsigned int rxd; | ||
| 101 | |||
| 102 | rxd = readl(hw->base + ALTERA_SPI_RXDATA); | ||
| 103 | if (hw->rx) { | ||
| 104 | switch (hw->bytes_per_word) { | ||
| 105 | case 1: | ||
| 106 | hw->rx[hw->count] = rxd; | ||
| 107 | break; | ||
| 108 | case 2: | ||
| 109 | hw->rx[hw->count * 2] = rxd; | ||
| 110 | hw->rx[hw->count * 2 + 1] = rxd >> 8; | ||
| 111 | break; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | hw->count++; | ||
| 91 | } | 116 | } |
| 92 | 117 | ||
| 93 | static int altera_spi_txrx(struct spi_master *master, | 118 | static int altera_spi_txrx(struct spi_master *master, |
| @@ -107,32 +132,16 @@ static int altera_spi_txrx(struct spi_master *master, | |||
| 107 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); | 132 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); |
| 108 | 133 | ||
| 109 | /* send the first byte */ | 134 | /* send the first byte */ |
| 110 | writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA); | 135 | altera_spi_tx_word(hw); |
| 111 | } else { | 136 | } else { |
| 112 | while (hw->count < hw->len) { | 137 | while (hw->count < hw->len) { |
| 113 | unsigned int rxd; | 138 | altera_spi_tx_word(hw); |
| 114 | |||
| 115 | writel(hw_txbyte(hw, hw->count), | ||
| 116 | hw->base + ALTERA_SPI_TXDATA); | ||
| 117 | 139 | ||
| 118 | while (!(readl(hw->base + ALTERA_SPI_STATUS) & | 140 | while (!(readl(hw->base + ALTERA_SPI_STATUS) & |
| 119 | ALTERA_SPI_STATUS_RRDY_MSK)) | 141 | ALTERA_SPI_STATUS_RRDY_MSK)) |
| 120 | cpu_relax(); | 142 | cpu_relax(); |
| 121 | 143 | ||
| 122 | rxd = readl(hw->base + ALTERA_SPI_RXDATA); | 144 | altera_spi_rx_word(hw); |
| 123 | if (hw->rx) { | ||
| 124 | switch (hw->bytes_per_word) { | ||
| 125 | case 1: | ||
| 126 | hw->rx[hw->count] = rxd; | ||
| 127 | break; | ||
| 128 | case 2: | ||
| 129 | hw->rx[hw->count * 2] = rxd; | ||
| 130 | hw->rx[hw->count * 2 + 1] = rxd >> 8; | ||
| 131 | break; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | hw->count++; | ||
| 136 | } | 145 | } |
| 137 | spi_finalize_current_transfer(master); | 146 | spi_finalize_current_transfer(master); |
| 138 | } | 147 | } |
| @@ -144,25 +153,11 @@ static irqreturn_t altera_spi_irq(int irq, void *dev) | |||
| 144 | { | 153 | { |
| 145 | struct spi_master *master = dev; | 154 | struct spi_master *master = dev; |
| 146 | struct altera_spi *hw = spi_master_get_devdata(master); | 155 | struct altera_spi *hw = spi_master_get_devdata(master); |
| 147 | unsigned int rxd; | ||
| 148 | |||
| 149 | rxd = readl(hw->base + ALTERA_SPI_RXDATA); | ||
| 150 | if (hw->rx) { | ||
| 151 | switch (hw->bytes_per_word) { | ||
| 152 | case 1: | ||
| 153 | hw->rx[hw->count] = rxd; | ||
| 154 | break; | ||
| 155 | case 2: | ||
| 156 | hw->rx[hw->count * 2] = rxd; | ||
| 157 | hw->rx[hw->count * 2 + 1] = rxd >> 8; | ||
| 158 | break; | ||
| 159 | } | ||
| 160 | } | ||
| 161 | 156 | ||
| 162 | hw->count++; | 157 | altera_spi_rx_word(hw); |
| 163 | 158 | ||
| 164 | if (hw->count < hw->len) { | 159 | if (hw->count < hw->len) { |
| 165 | writel(hw_txbyte(hw, hw->count), hw->base + ALTERA_SPI_TXDATA); | 160 | altera_spi_tx_word(hw); |
| 166 | } else { | 161 | } else { |
| 167 | /* disable receive interrupt */ | 162 | /* disable receive interrupt */ |
| 168 | hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK; | 163 | hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK; |
