aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorFeng Tang <feng.tang@intel.com>2011-03-30 11:09:52 -0400
committerGrant Likely <grant.likely@secretlab.ca>2011-03-30 23:31:48 -0400
commitde6efe0a966cf86b3c4039a610b2d4157db707f2 (patch)
tree1eae388ca7196ea94d5480174d5f69fd1b43d588 /drivers/spi
parent0ce790e7d736cedc563e1fb4e998babf5a4dbc3d (diff)
spi/dw_spi: unify the low level read/write routines
The original version has many duplicated codes for null/u8/u16 case, so unify them to make it cleaner Signed-off-by: Feng Tang <feng.tang@intel.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/dw_spi.c103
-rw-r--r--drivers/spi/dw_spi.h2
2 files changed, 26 insertions, 79 deletions
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c
index 9a6196461b27..c4fca3d9d45f 100644
--- a/drivers/spi/dw_spi.c
+++ b/drivers/spi/dw_spi.c
@@ -58,8 +58,6 @@ struct chip_data {
58 u8 bits_per_word; 58 u8 bits_per_word;
59 u16 clk_div; /* baud rate divider */ 59 u16 clk_div; /* baud rate divider */
60 u32 speed_hz; /* baud rate */ 60 u32 speed_hz; /* baud rate */
61 int (*write)(struct dw_spi *dws);
62 int (*read)(struct dw_spi *dws);
63 void (*cs_control)(u32 command); 61 void (*cs_control)(u32 command);
64}; 62};
65 63
@@ -185,80 +183,45 @@ static void flush(struct dw_spi *dws)
185 wait_till_not_busy(dws); 183 wait_till_not_busy(dws);
186} 184}
187 185
188static int null_writer(struct dw_spi *dws)
189{
190 u8 n_bytes = dws->n_bytes;
191
192 if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL)
193 || (dws->tx == dws->tx_end))
194 return 0;
195 dw_writew(dws, dr, 0);
196 dws->tx += n_bytes;
197 186
198 wait_till_not_busy(dws); 187static int dw_writer(struct dw_spi *dws)
199 return 1;
200}
201
202static int null_reader(struct dw_spi *dws)
203{ 188{
204 u8 n_bytes = dws->n_bytes; 189 u16 txw = 0;
205 190
206 while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT)
207 && (dws->rx < dws->rx_end)) {
208 dw_readw(dws, dr);
209 dws->rx += n_bytes;
210 }
211 wait_till_not_busy(dws);
212 return dws->rx == dws->rx_end;
213}
214
215static int u8_writer(struct dw_spi *dws)
216{
217 if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL) 191 if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL)
218 || (dws->tx == dws->tx_end)) 192 || (dws->tx == dws->tx_end))
219 return 0; 193 return 0;
220 194
221 dw_writew(dws, dr, *(u8 *)(dws->tx)); 195 /* Set the tx word if the transfer's original "tx" is not null */
222 ++dws->tx; 196 if (dws->tx_end - dws->len) {
223 197 if (dws->n_bytes == 1)
224 wait_till_not_busy(dws); 198 txw = *(u8 *)(dws->tx);
225 return 1; 199 else
226} 200 txw = *(u16 *)(dws->tx);
227
228static int u8_reader(struct dw_spi *dws)
229{
230 while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT)
231 && (dws->rx < dws->rx_end)) {
232 *(u8 *)(dws->rx) = dw_readw(dws, dr);
233 ++dws->rx;
234 } 201 }
235 202
236 wait_till_not_busy(dws); 203 dw_writew(dws, dr, txw);
237 return dws->rx == dws->rx_end; 204 dws->tx += dws->n_bytes;
238}
239
240static int u16_writer(struct dw_spi *dws)
241{
242 if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL)
243 || (dws->tx == dws->tx_end))
244 return 0;
245
246 dw_writew(dws, dr, *(u16 *)(dws->tx));
247 dws->tx += 2;
248 205
249 wait_till_not_busy(dws); 206 wait_till_not_busy(dws);
250 return 1; 207 return 1;
251} 208}
252 209
253static int u16_reader(struct dw_spi *dws) 210static int dw_reader(struct dw_spi *dws)
254{ 211{
255 u16 temp; 212 u16 rxw;
256 213
257 while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT) 214 while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT)
258 && (dws->rx < dws->rx_end)) { 215 && (dws->rx < dws->rx_end)) {
259 temp = dw_readw(dws, dr); 216 rxw = dw_readw(dws, dr);
260 *(u16 *)(dws->rx) = temp; 217 /* Care rx only if the transfer's original "rx" is not null */
261 dws->rx += 2; 218 if (dws->rx_end - dws->len) {
219 if (dws->n_bytes == 1)
220 *(u8 *)(dws->rx) = rxw;
221 else
222 *(u16 *)(dws->rx) = rxw;
223 }
224 dws->rx += dws->n_bytes;
262 } 225 }
263 226
264 wait_till_not_busy(dws); 227 wait_till_not_busy(dws);
@@ -383,8 +346,8 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
383 left = (left > int_level) ? int_level : left; 346 left = (left > int_level) ? int_level : left;
384 347
385 while (left--) 348 while (left--)
386 dws->write(dws); 349 dw_writer(dws);
387 dws->read(dws); 350 dw_reader(dws);
388 351
389 /* Re-enable the IRQ if there is still data left to tx */ 352 /* Re-enable the IRQ if there is still data left to tx */
390 if (dws->tx_end > dws->tx) 353 if (dws->tx_end > dws->tx)
@@ -417,13 +380,13 @@ static irqreturn_t dw_spi_irq(int irq, void *dev_id)
417/* Must be called inside pump_transfers() */ 380/* Must be called inside pump_transfers() */
418static void poll_transfer(struct dw_spi *dws) 381static void poll_transfer(struct dw_spi *dws)
419{ 382{
420 while (dws->write(dws)) 383 while (dw_writer(dws))
421 dws->read(dws); 384 dw_reader(dws);
422 /* 385 /*
423 * There is a possibility that the last word of a transaction 386 * There is a possibility that the last word of a transaction
424 * will be lost if data is not ready. Re-read to solve this issue. 387 * will be lost if data is not ready. Re-read to solve this issue.
425 */ 388 */
426 dws->read(dws); 389 dw_reader(dws);
427 390
428 dw_spi_xfer_done(dws); 391 dw_spi_xfer_done(dws);
429} 392}
@@ -483,8 +446,6 @@ static void pump_transfers(unsigned long data)
483 dws->tx_end = dws->tx + transfer->len; 446 dws->tx_end = dws->tx + transfer->len;
484 dws->rx = transfer->rx_buf; 447 dws->rx = transfer->rx_buf;
485 dws->rx_end = dws->rx + transfer->len; 448 dws->rx_end = dws->rx + transfer->len;
486 dws->write = dws->tx ? chip->write : null_writer;
487 dws->read = dws->rx ? chip->read : null_reader;
488 dws->cs_change = transfer->cs_change; 449 dws->cs_change = transfer->cs_change;
489 dws->len = dws->cur_transfer->len; 450 dws->len = dws->cur_transfer->len;
490 if (chip != dws->prev_chip) 451 if (chip != dws->prev_chip)
@@ -520,18 +481,10 @@ static void pump_transfers(unsigned long data)
520 case 8: 481 case 8:
521 dws->n_bytes = 1; 482 dws->n_bytes = 1;
522 dws->dma_width = 1; 483 dws->dma_width = 1;
523 dws->read = (dws->read != null_reader) ?
524 u8_reader : null_reader;
525 dws->write = (dws->write != null_writer) ?
526 u8_writer : null_writer;
527 break; 484 break;
528 case 16: 485 case 16:
529 dws->n_bytes = 2; 486 dws->n_bytes = 2;
530 dws->dma_width = 2; 487 dws->dma_width = 2;
531 dws->read = (dws->read != null_reader) ?
532 u16_reader : null_reader;
533 dws->write = (dws->write != null_writer) ?
534 u16_writer : null_writer;
535 break; 488 break;
536 default: 489 default:
537 printk(KERN_ERR "MRST SPI0: unsupported bits:" 490 printk(KERN_ERR "MRST SPI0: unsupported bits:"
@@ -733,13 +686,9 @@ static int dw_spi_setup(struct spi_device *spi)
733 if (spi->bits_per_word <= 8) { 686 if (spi->bits_per_word <= 8) {
734 chip->n_bytes = 1; 687 chip->n_bytes = 1;
735 chip->dma_width = 1; 688 chip->dma_width = 1;
736 chip->read = u8_reader;
737 chip->write = u8_writer;
738 } else if (spi->bits_per_word <= 16) { 689 } else if (spi->bits_per_word <= 16) {
739 chip->n_bytes = 2; 690 chip->n_bytes = 2;
740 chip->dma_width = 2; 691 chip->dma_width = 2;
741 chip->read = u16_reader;
742 chip->write = u16_writer;
743 } else { 692 } else {
744 /* Never take >16b case for MRST SPIC */ 693 /* Never take >16b case for MRST SPIC */
745 dev_err(&spi->dev, "invalid wordsize\n"); 694 dev_err(&spi->dev, "invalid wordsize\n");
diff --git a/drivers/spi/dw_spi.h b/drivers/spi/dw_spi.h
index fb0bce564844..d8aac1f4c546 100644
--- a/drivers/spi/dw_spi.h
+++ b/drivers/spi/dw_spi.h
@@ -137,8 +137,6 @@ struct dw_spi {
137 u8 max_bits_per_word; /* maxim is 16b */ 137 u8 max_bits_per_word; /* maxim is 16b */
138 u32 dma_width; 138 u32 dma_width;
139 int cs_change; 139 int cs_change;
140 int (*write)(struct dw_spi *dws);
141 int (*read)(struct dw_spi *dws);
142 irqreturn_t (*transfer_handler)(struct dw_spi *dws); 140 irqreturn_t (*transfer_handler)(struct dw_spi *dws);
143 void (*cs_control)(u32 command); 141 void (*cs_control)(u32 command);
144 142