aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-07-27 07:21:52 -0400
committerMark Brown <broonie@linaro.org>2013-07-29 12:12:35 -0400
commitbb249aad82b93674281d8b76a0c9be2ba1d92d78 (patch)
treec2c81de29e0414d871d3f33c405b5c21bba97592
parent5ae90d8e467e625e447000cb4335c4db973b1095 (diff)
spi/tegra114: Factor runtime PM out into transfer prepare/unprepare
Currently the tegra114 driver acquires a runtime PM reference for the duration of each transfer. This may result in the IP being powered down between transfers which would be at best wasteful. Instead it is better to do this in the callbacks that are generated before and after starting a series of transfers, keeping the IP powered throughout. Signed-off-by: Mark Brown <broonie@linaro.org> Acked-by: Laxman Dewangan <ldewangan@nvidia.com>
-rw-r--r--drivers/spi/spi-tegra114.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index e8f542ab8935..d85882da8532 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -803,6 +803,20 @@ static int tegra_spi_setup(struct spi_device *spi)
803 return 0; 803 return 0;
804} 804}
805 805
806static int tegra_spi_prepare_transfer(struct spi_master *spi)
807{
808 struct tegra_spi_data *tspi = spi_master_get_devdata(spi);
809 int ret;
810
811 ret = pm_runtime_get_sync(tspi->dev);
812 if (ret < 0) {
813 dev_err(tspi->dev, "runtime PM get failed: %d\n", ret);
814 return ret;
815 }
816
817 return ret;
818}
819
806static int tegra_spi_transfer_one_message(struct spi_master *master, 820static int tegra_spi_transfer_one_message(struct spi_master *master,
807 struct spi_message *msg) 821 struct spi_message *msg)
808{ 822{
@@ -816,14 +830,6 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,
816 msg->status = 0; 830 msg->status = 0;
817 msg->actual_length = 0; 831 msg->actual_length = 0;
818 832
819 ret = pm_runtime_get_sync(tspi->dev);
820 if (ret < 0) {
821 dev_err(tspi->dev, "runtime PM get failed: %d\n", ret);
822 msg->status = ret;
823 spi_finalize_current_message(master);
824 return ret;
825 }
826
827 single_xfer = list_is_singular(&msg->transfers); 833 single_xfer = list_is_singular(&msg->transfers);
828 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 834 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
829 INIT_COMPLETION(tspi->xfer_completion); 835 INIT_COMPLETION(tspi->xfer_completion);
@@ -859,12 +865,20 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,
859 ret = 0; 865 ret = 0;
860exit: 866exit:
861 tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); 867 tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
862 pm_runtime_put(tspi->dev);
863 msg->status = ret; 868 msg->status = ret;
864 spi_finalize_current_message(master); 869 spi_finalize_current_message(master);
865 return ret; 870 return ret;
866} 871}
867 872
873static int tegra_spi_unprepare_transfer(struct spi_master *spi)
874{
875 struct tegra_spi_data *tspi = spi_master_get_devdata(spi);
876
877 pm_runtime_put(tspi->dev);
878
879 return 0;
880}
881
868static irqreturn_t handle_cpu_based_xfer(struct tegra_spi_data *tspi) 882static irqreturn_t handle_cpu_based_xfer(struct tegra_spi_data *tspi)
869{ 883{
870 struct spi_transfer *t = tspi->curr_xfer; 884 struct spi_transfer *t = tspi->curr_xfer;
@@ -1050,7 +1064,9 @@ static int tegra_spi_probe(struct platform_device *pdev)
1050 /* the spi->mode bits understood by this driver: */ 1064 /* the spi->mode bits understood by this driver: */
1051 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 1065 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
1052 master->setup = tegra_spi_setup; 1066 master->setup = tegra_spi_setup;
1067 master->prepare_transfer_hardware = tegra_spi_prepare_transfer;
1053 master->transfer_one_message = tegra_spi_transfer_one_message; 1068 master->transfer_one_message = tegra_spi_transfer_one_message;
1069 master->unprepare_transfer_hardware = tegra_spi_unprepare_transfer;
1054 master->num_chipselect = MAX_CHIP_SELECT; 1070 master->num_chipselect = MAX_CHIP_SELECT;
1055 master->bus_num = -1; 1071 master->bus_num = -1;
1056 1072