Commit 0faa3146f17295f612abadafbfe3d4346178f10f

Authored by Mark Brown

Merge remote-tracking branch 'spi/fix/atmel' into spi-linus

Showing 1 changed file Side-by-side Diff

drivers/spi/spi-atmel.c
... ... @@ -526,13 +526,17 @@
526 526 }
527 527  
528 528 if (xfer->tx_buf)
529   - spi_writel(as, TDR, *(u8 *)(xfer->tx_buf));
  529 + if (xfer->bits_per_word > 8)
  530 + spi_writel(as, TDR, *(u16 *)(xfer->tx_buf));
  531 + else
  532 + spi_writel(as, TDR, *(u8 *)(xfer->tx_buf));
530 533 else
531 534 spi_writel(as, TDR, 0);
532 535  
533 536 dev_dbg(master->dev.parent,
534   - " start pio xfer %p: len %u tx %p rx %p\n",
535   - xfer, xfer->len, xfer->tx_buf, xfer->rx_buf);
  537 + " start pio xfer %p: len %u tx %p rx %p bitpw %d\n",
  538 + xfer, xfer->len, xfer->tx_buf, xfer->rx_buf,
  539 + xfer->bits_per_word);
536 540  
537 541 /* Enable relevant interrupts */
538 542 spi_writel(as, IER, SPI_BIT(RDRF) | SPI_BIT(OVRES));
539 543  
540 544  
541 545  
542 546  
... ... @@ -950,21 +954,39 @@
950 954 {
951 955 u8 *txp;
952 956 u8 *rxp;
  957 + u16 *txp16;
  958 + u16 *rxp16;
953 959 unsigned long xfer_pos = xfer->len - as->current_remaining_bytes;
954 960  
955 961 if (xfer->rx_buf) {
956   - rxp = ((u8 *)xfer->rx_buf) + xfer_pos;
957   - *rxp = spi_readl(as, RDR);
  962 + if (xfer->bits_per_word > 8) {
  963 + rxp16 = (u16 *)(((u8 *)xfer->rx_buf) + xfer_pos);
  964 + *rxp16 = spi_readl(as, RDR);
  965 + } else {
  966 + rxp = ((u8 *)xfer->rx_buf) + xfer_pos;
  967 + *rxp = spi_readl(as, RDR);
  968 + }
958 969 } else {
959 970 spi_readl(as, RDR);
960 971 }
  972 + if (xfer->bits_per_word > 8) {
  973 + as->current_remaining_bytes -= 2;
  974 + if (as->current_remaining_bytes < 0)
  975 + as->current_remaining_bytes = 0;
  976 + } else {
  977 + as->current_remaining_bytes--;
  978 + }
961 979  
962   - as->current_remaining_bytes--;
963   -
964 980 if (as->current_remaining_bytes) {
965 981 if (xfer->tx_buf) {
966   - txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1;
967   - spi_writel(as, TDR, *txp);
  982 + if (xfer->bits_per_word > 8) {
  983 + txp16 = (u16 *)(((u8 *)xfer->tx_buf)
  984 + + xfer_pos + 2);
  985 + spi_writel(as, TDR, *txp16);
  986 + } else {
  987 + txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1;
  988 + spi_writel(as, TDR, *txp);
  989 + }
968 990 } else {
969 991 spi_writel(as, TDR, 0);
970 992 }
... ... @@ -1375,6 +1397,13 @@
1375 1397 dev_dbg(&spi->dev, "you can't yet change "
1376 1398 "bits_per_word in transfers\n");
1377 1399 return -ENOPROTOOPT;
  1400 + }
  1401 + }
  1402 +
  1403 + if (xfer->bits_per_word > 8) {
  1404 + if (xfer->len % 2) {
  1405 + dev_dbg(&spi->dev, "buffer len should be 16 bits aligned\n");
  1406 + return -EINVAL;
1378 1407 }
1379 1408 }
1380 1409