aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-tegra20-slink.c
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-10-05 07:23:38 -0400
committerMark Brown <broonie@linaro.org>2013-10-17 05:57:47 -0400
commit63fc184cde2d771affc2e7885c05a2792bae9f86 (patch)
tree2876e182ab6c39159dff711d30ac551fac369527 /drivers/spi/spi-tegra20-slink.c
parent3cb7b407ce84e5756076f64bf4341cc101955966 (diff)
spi/tegra20-slink: Crude refactoring to use core message parsing
This is a half done conversion with minimal code reorganisation provided for bisection purposes. A further patch will move the first transfer preparation into tegra_slink_prepare_message(). The cs_change and udelay handling is removed, these should be implemented by the framework and in any case are buggy - the two fields should not be related and the cs_change handling appears to at best only work the first time it's used in a message. Signed-off-by: Mark Brown <broonie@linaro.org> Tested-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'drivers/spi/spi-tegra20-slink.c')
-rw-r--r--drivers/spi/spi-tegra20-slink.c88
1 files changed, 46 insertions, 42 deletions
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c
index d1d2bff01301..3576fcb3f79b 100644
--- a/drivers/spi/spi-tegra20-slink.c
+++ b/drivers/spi/spi-tegra20-slink.c
@@ -196,6 +196,7 @@ struct tegra_slink_data {
196 u32 rx_status; 196 u32 rx_status;
197 u32 status_reg; 197 u32 status_reg;
198 bool is_packed; 198 bool is_packed;
199 bool is_first_msg;
199 unsigned long packed_size; 200 unsigned long packed_size;
200 201
201 u32 command_reg; 202 u32 command_reg;
@@ -823,55 +824,56 @@ static int tegra_slink_setup(struct spi_device *spi)
823 return 0; 824 return 0;
824} 825}
825 826
826static int tegra_slink_transfer_one_message(struct spi_master *master, 827static int tegra_slink_prepare_message(struct spi_master *master,
827 struct spi_message *msg) 828 struct spi_message *msg)
828{ 829{
829 bool is_first_msg = true;
830 struct tegra_slink_data *tspi = spi_master_get_devdata(master); 830 struct tegra_slink_data *tspi = spi_master_get_devdata(master);
831 struct spi_transfer *xfer;
832 struct spi_device *spi = msg->spi;
833 int ret;
834 831
835 msg->status = 0; 832 tspi->is_first_msg = true;
836 msg->actual_length = 0;
837 833
838 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 834 return 0;
839 INIT_COMPLETION(tspi->xfer_completion); 835}
840 ret = tegra_slink_start_transfer_one(spi, xfer, is_first_msg);
841 if (ret < 0) {
842 dev_err(tspi->dev,
843 "spi can not start transfer, err %d\n", ret);
844 goto exit;
845 }
846 is_first_msg = false;
847 ret = wait_for_completion_timeout(&tspi->xfer_completion,
848 SLINK_DMA_TIMEOUT);
849 if (WARN_ON(ret == 0)) {
850 dev_err(tspi->dev,
851 "spi trasfer timeout, err %d\n", ret);
852 ret = -EIO;
853 goto exit;
854 }
855 836
856 if (tspi->tx_status || tspi->rx_status) { 837static int tegra_slink_transfer_one(struct spi_master *master,
857 dev_err(tspi->dev, "Error in Transfer\n"); 838 struct spi_device *spi,
858 ret = -EIO; 839 struct spi_transfer *xfer)
859 goto exit; 840{
860 } 841 struct tegra_slink_data *tspi = spi_master_get_devdata(master);
861 msg->actual_length += xfer->len; 842 int ret;
862 if (xfer->cs_change && xfer->delay_usecs) { 843
863 tegra_slink_writel(tspi, tspi->def_command_reg, 844 INIT_COMPLETION(tspi->xfer_completion);
864 SLINK_COMMAND); 845 ret = tegra_slink_start_transfer_one(spi, xfer, tspi->is_first_msg);
865 udelay(xfer->delay_usecs); 846 if (ret < 0) {
866 } 847 dev_err(tspi->dev,
848 "spi can not start transfer, err %d\n", ret);
849 return ret;
867 } 850 }
868 ret = 0; 851 tspi->is_first_msg = false;
869exit: 852 ret = wait_for_completion_timeout(&tspi->xfer_completion,
853 SLINK_DMA_TIMEOUT);
854 if (WARN_ON(ret == 0)) {
855 dev_err(tspi->dev,
856 "spi trasfer timeout, err %d\n", ret);
857 return -EIO;
858 }
859
860 if (tspi->tx_status)
861 return tspi->tx_status;
862 if (tspi->rx_status)
863 return tspi->rx_status;
864
865 return 0;
866}
867
868static int tegra_slink_unprepare_message(struct spi_master *master,
869 struct spi_message *msg)
870{
871 struct tegra_slink_data *tspi = spi_master_get_devdata(master);
872
870 tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); 873 tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND);
871 tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); 874 tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2);
872 msg->status = ret; 875
873 spi_finalize_current_message(master); 876 return 0;
874 return ret;
875} 877}
876 878
877static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi) 879static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi)
@@ -1074,7 +1076,9 @@ static int tegra_slink_probe(struct platform_device *pdev)
1074 /* the spi->mode bits understood by this driver: */ 1076 /* the spi->mode bits understood by this driver: */
1075 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 1077 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
1076 master->setup = tegra_slink_setup; 1078 master->setup = tegra_slink_setup;
1077 master->transfer_one_message = tegra_slink_transfer_one_message; 1079 master->prepare_message = tegra_slink_prepare_message;
1080 master->transfer_one = tegra_slink_transfer_one;
1081 master->unprepare_message = tegra_slink_unprepare_message;
1078 master->auto_runtime_pm = true; 1082 master->auto_runtime_pm = true;
1079 master->num_chipselect = MAX_CHIP_SELECT; 1083 master->num_chipselect = MAX_CHIP_SELECT;
1080 master->bus_num = -1; 1084 master->bus_num = -1;