Commit 0faa3146f17295f612abadafbfe3d4346178f10f
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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 |