diff options
| -rw-r--r-- | drivers/spi/spi_bfin5xx.c | 58 |
1 files changed, 32 insertions, 26 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 40d9f64c7fa0..b0de61a014f5 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
| @@ -42,6 +42,14 @@ MODULE_LICENSE("GPL"); | |||
| 42 | #define DONE_STATE ((void *)2) | 42 | #define DONE_STATE ((void *)2) |
| 43 | #define ERROR_STATE ((void *)-1) | 43 | #define ERROR_STATE ((void *)-1) |
| 44 | 44 | ||
| 45 | struct driver_data; | ||
| 46 | |||
| 47 | struct transfer_ops { | ||
| 48 | void (*write) (struct driver_data *); | ||
| 49 | void (*read) (struct driver_data *); | ||
| 50 | void (*duplex) (struct driver_data *); | ||
| 51 | }; | ||
| 52 | |||
| 45 | struct driver_data { | 53 | struct driver_data { |
| 46 | /* Driver model hookup */ | 54 | /* Driver model hookup */ |
| 47 | struct platform_device *pdev; | 55 | struct platform_device *pdev; |
| @@ -94,9 +102,7 @@ struct driver_data { | |||
| 94 | size_t tx_map_len; | 102 | size_t tx_map_len; |
| 95 | u8 n_bytes; | 103 | u8 n_bytes; |
| 96 | int cs_change; | 104 | int cs_change; |
| 97 | void (*write) (struct driver_data *); | 105 | const struct transfer_ops *ops; |
| 98 | void (*read) (struct driver_data *); | ||
| 99 | void (*duplex) (struct driver_data *); | ||
| 100 | }; | 106 | }; |
| 101 | 107 | ||
| 102 | struct chip_data { | 108 | struct chip_data { |
| @@ -113,9 +119,7 @@ struct chip_data { | |||
| 113 | u32 cs_gpio; | 119 | u32 cs_gpio; |
| 114 | u16 idle_tx_val; | 120 | u16 idle_tx_val; |
| 115 | u8 pio_interrupt; /* use spi data irq */ | 121 | u8 pio_interrupt; /* use spi data irq */ |
| 116 | void (*write) (struct driver_data *); | 122 | const struct transfer_ops *ops; |
| 117 | void (*read) (struct driver_data *); | ||
| 118 | void (*duplex) (struct driver_data *); | ||
| 119 | }; | 123 | }; |
| 120 | 124 | ||
| 121 | #define DEFINE_SPI_REG(reg, off) \ | 125 | #define DEFINE_SPI_REG(reg, off) \ |
| @@ -294,6 +298,12 @@ static void bfin_spi_u8_duplex(struct driver_data *drv_data) | |||
| 294 | } | 298 | } |
| 295 | } | 299 | } |
| 296 | 300 | ||
| 301 | static const struct transfer_ops bfin_transfer_ops_u8 = { | ||
| 302 | .write = bfin_spi_u8_writer, | ||
| 303 | .read = bfin_spi_u8_reader, | ||
| 304 | .duplex = bfin_spi_u8_duplex, | ||
| 305 | }; | ||
| 306 | |||
| 297 | static void bfin_spi_u16_writer(struct driver_data *drv_data) | 307 | static void bfin_spi_u16_writer(struct driver_data *drv_data) |
| 298 | { | 308 | { |
| 299 | /* clear RXS (we check for RXS inside the loop) */ | 309 | /* clear RXS (we check for RXS inside the loop) */ |
| @@ -342,6 +352,12 @@ static void bfin_spi_u16_duplex(struct driver_data *drv_data) | |||
| 342 | } | 352 | } |
| 343 | } | 353 | } |
| 344 | 354 | ||
| 355 | static const struct transfer_ops bfin_transfer_ops_u16 = { | ||
| 356 | .write = bfin_spi_u16_writer, | ||
| 357 | .read = bfin_spi_u16_reader, | ||
| 358 | .duplex = bfin_spi_u16_duplex, | ||
| 359 | }; | ||
| 360 | |||
| 345 | /* test if ther is more transfer to be done */ | 361 | /* test if ther is more transfer to be done */ |
| 346 | static void *bfin_spi_next_transfer(struct driver_data *drv_data) | 362 | static void *bfin_spi_next_transfer(struct driver_data *drv_data) |
| 347 | { | 363 | { |
| @@ -620,17 +636,13 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
| 620 | case 8: | 636 | case 8: |
| 621 | drv_data->n_bytes = 1; | 637 | drv_data->n_bytes = 1; |
| 622 | width = CFG_SPI_WORDSIZE8; | 638 | width = CFG_SPI_WORDSIZE8; |
| 623 | drv_data->read = bfin_spi_u8_reader; | 639 | drv_data->ops = &bfin_transfer_ops_u8; |
| 624 | drv_data->write = bfin_spi_u8_writer; | ||
| 625 | drv_data->duplex = bfin_spi_u8_duplex; | ||
| 626 | break; | 640 | break; |
| 627 | 641 | ||
| 628 | case 16: | 642 | case 16: |
| 629 | drv_data->n_bytes = 2; | 643 | drv_data->n_bytes = 2; |
| 630 | width = CFG_SPI_WORDSIZE16; | 644 | width = CFG_SPI_WORDSIZE16; |
| 631 | drv_data->read = bfin_spi_u16_reader; | 645 | drv_data->ops = &bfin_transfer_ops_u16; |
| 632 | drv_data->write = bfin_spi_u16_writer; | ||
| 633 | drv_data->duplex = bfin_spi_u16_duplex; | ||
| 634 | break; | 646 | break; |
| 635 | 647 | ||
| 636 | default: | 648 | default: |
| @@ -638,9 +650,7 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
| 638 | transfer->bits_per_word = chip->bits_per_word; | 650 | transfer->bits_per_word = chip->bits_per_word; |
| 639 | drv_data->n_bytes = chip->n_bytes; | 651 | drv_data->n_bytes = chip->n_bytes; |
| 640 | width = chip->width; | 652 | width = chip->width; |
| 641 | drv_data->write = chip->write; | 653 | drv_data->ops = chip->ops; |
| 642 | drv_data->read = chip->read; | ||
| 643 | drv_data->duplex = chip->duplex; | ||
| 644 | break; | 654 | break; |
| 645 | } | 655 | } |
| 646 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); | 656 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); |
| @@ -653,8 +663,8 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
| 653 | drv_data->len = transfer->len; | 663 | drv_data->len = transfer->len; |
| 654 | } | 664 | } |
| 655 | dev_dbg(&drv_data->pdev->dev, | 665 | dev_dbg(&drv_data->pdev->dev, |
| 656 | "transfer: drv_data->write is %p, chip->write is %p\n", | 666 | "transfer: drv_data->ops is %p, chip->ops is %p, u8_ops is %p\n", |
| 657 | drv_data->write, chip->write); | 667 | drv_data->ops, chip->ops, &bfin_transfer_ops_u8); |
| 658 | 668 | ||
| 659 | message->state = RUNNING_STATE; | 669 | message->state = RUNNING_STATE; |
| 660 | dma_config = 0; | 670 | dma_config = 0; |
| @@ -819,7 +829,7 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
| 819 | dev_dbg(&drv_data->pdev->dev, | 829 | dev_dbg(&drv_data->pdev->dev, |
| 820 | "IO duplex: cr is 0x%x\n", cr); | 830 | "IO duplex: cr is 0x%x\n", cr); |
| 821 | 831 | ||
| 822 | drv_data->duplex(drv_data); | 832 | drv_data->ops->duplex(drv_data); |
| 823 | 833 | ||
| 824 | if (drv_data->tx != drv_data->tx_end) | 834 | if (drv_data->tx != drv_data->tx_end) |
| 825 | tranf_success = 0; | 835 | tranf_success = 0; |
| @@ -828,7 +838,7 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
| 828 | dev_dbg(&drv_data->pdev->dev, | 838 | dev_dbg(&drv_data->pdev->dev, |
| 829 | "IO write: cr is 0x%x\n", cr); | 839 | "IO write: cr is 0x%x\n", cr); |
| 830 | 840 | ||
| 831 | drv_data->write(drv_data); | 841 | drv_data->ops->write(drv_data); |
| 832 | 842 | ||
| 833 | if (drv_data->tx != drv_data->tx_end) | 843 | if (drv_data->tx != drv_data->tx_end) |
| 834 | tranf_success = 0; | 844 | tranf_success = 0; |
| @@ -837,7 +847,7 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
| 837 | dev_dbg(&drv_data->pdev->dev, | 847 | dev_dbg(&drv_data->pdev->dev, |
| 838 | "IO read: cr is 0x%x\n", cr); | 848 | "IO read: cr is 0x%x\n", cr); |
| 839 | 849 | ||
| 840 | drv_data->read(drv_data); | 850 | drv_data->ops->read(drv_data); |
| 841 | if (drv_data->rx != drv_data->rx_end) | 851 | if (drv_data->rx != drv_data->rx_end) |
| 842 | tranf_success = 0; | 852 | tranf_success = 0; |
| 843 | } | 853 | } |
| @@ -1032,17 +1042,13 @@ static int bfin_spi_setup(struct spi_device *spi) | |||
| 1032 | case 8: | 1042 | case 8: |
| 1033 | chip->n_bytes = 1; | 1043 | chip->n_bytes = 1; |
| 1034 | chip->width = CFG_SPI_WORDSIZE8; | 1044 | chip->width = CFG_SPI_WORDSIZE8; |
| 1035 | chip->read = bfin_spi_u8_reader; | 1045 | chip->ops = &bfin_transfer_ops_u8; |
| 1036 | chip->write = bfin_spi_u8_writer; | ||
| 1037 | chip->duplex = bfin_spi_u8_duplex; | ||
| 1038 | break; | 1046 | break; |
| 1039 | 1047 | ||
| 1040 | case 16: | 1048 | case 16: |
| 1041 | chip->n_bytes = 2; | 1049 | chip->n_bytes = 2; |
| 1042 | chip->width = CFG_SPI_WORDSIZE16; | 1050 | chip->width = CFG_SPI_WORDSIZE16; |
| 1043 | chip->read = bfin_spi_u16_reader; | 1051 | chip->ops = &bfin_transfer_ops_u16; |
| 1044 | chip->write = bfin_spi_u16_writer; | ||
| 1045 | chip->duplex = bfin_spi_u16_duplex; | ||
| 1046 | break; | 1052 | break; |
| 1047 | 1053 | ||
| 1048 | default: | 1054 | default: |
