Commit 307c897d authored by Marc Kleine-Budde's avatar Marc Kleine-Budde Committed by Mark Brown

spi: spi-imx: replace struct spi_imx_data::bitbang by pointer to struct spi_controller

There's no need to embed the struct spi_bitbang into our private
data (struct spi_imx_data), the spi core is flexible enough, so that
we only need a pointer to the allocated struct spi_controller.

This is also a preparation patch to add PIO based polling support to
the driver.
Co-developed-by: default avatarDavid Jander <david@protonic.nl>
Signed-off-by: default avatarDavid Jander <david@protonic.nl>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
Link: https://lore.kernel.org/r/20220502175457.1977983-8-mkl@pengutronix.deSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 63cd96b7
...@@ -414,7 +414,6 @@ config SPI_IMG_SPFI ...@@ -414,7 +414,6 @@ config SPI_IMG_SPFI
config SPI_IMX config SPI_IMX
tristate "Freescale i.MX SPI controllers" tristate "Freescale i.MX SPI controllers"
depends on ARCH_MXC || COMPILE_TEST depends on ARCH_MXC || COMPILE_TEST
select SPI_BITBANG
help help
This enables support for the Freescale i.MX SPI controllers. This enables support for the Freescale i.MX SPI controllers.
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
...@@ -86,7 +85,7 @@ struct spi_imx_devtype_data { ...@@ -86,7 +85,7 @@ struct spi_imx_devtype_data {
}; };
struct spi_imx_data { struct spi_imx_data {
struct spi_bitbang bitbang; struct spi_controller *controller;
struct device *dev; struct device *dev;
struct completion xfer_done; struct completion xfer_done;
...@@ -580,7 +579,7 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, ...@@ -580,7 +579,7 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
* the SPI communication as the device on the other end would consider * the SPI communication as the device on the other end would consider
* the change of SCLK polarity as a clock tick already. * the change of SCLK polarity as a clock tick already.
* *
* Because spi_imx->spi_bus_clk is only set in bitbang prepare_message * Because spi_imx->spi_bus_clk is only set in prepare_message
* callback, iterate over all the transfers in spi_message, find the * callback, iterate over all the transfers in spi_message, find the
* one with lowest bus frequency, and use that bus frequency for the * one with lowest bus frequency, and use that bus frequency for the
* delay calculation. In case all transfers have speed_hz == 0, then * delay calculation. In case all transfers have speed_hz == 0, then
...@@ -1261,7 +1260,7 @@ static int spi_imx_setupxfer(struct spi_device *spi, ...@@ -1261,7 +1260,7 @@ static int spi_imx_setupxfer(struct spi_device *spi,
spi_imx->dynamic_burst = 0; spi_imx->dynamic_burst = 0;
} }
if (spi_imx_can_dma(spi_imx->bitbang.master, spi, t)) if (spi_imx_can_dma(spi_imx->controller, spi, t))
spi_imx->usedma = true; spi_imx->usedma = true;
else else
spi_imx->usedma = false; spi_imx->usedma = false;
...@@ -1282,7 +1281,7 @@ static int spi_imx_setupxfer(struct spi_device *spi, ...@@ -1282,7 +1281,7 @@ static int spi_imx_setupxfer(struct spi_device *spi,
static void spi_imx_sdma_exit(struct spi_imx_data *spi_imx) static void spi_imx_sdma_exit(struct spi_imx_data *spi_imx)
{ {
struct spi_controller *controller = spi_imx->bitbang.master; struct spi_controller *controller = spi_imx->controller;
if (controller->dma_rx) { if (controller->dma_rx) {
dma_release_channel(controller->dma_rx); dma_release_channel(controller->dma_rx);
...@@ -1324,7 +1323,7 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, ...@@ -1324,7 +1323,7 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
init_completion(&spi_imx->dma_tx_completion); init_completion(&spi_imx->dma_tx_completion);
controller->can_dma = spi_imx_can_dma; controller->can_dma = spi_imx_can_dma;
controller->max_dma_len = MAX_SDMA_BD_BYTES; controller->max_dma_len = MAX_SDMA_BD_BYTES;
spi_imx->bitbang.master->flags = SPI_CONTROLLER_MUST_RX | spi_imx->controller->flags = SPI_CONTROLLER_MUST_RX |
SPI_CONTROLLER_MUST_TX; SPI_CONTROLLER_MUST_TX;
return 0; return 0;
...@@ -1367,7 +1366,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, ...@@ -1367,7 +1366,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
struct dma_async_tx_descriptor *desc_tx, *desc_rx; struct dma_async_tx_descriptor *desc_tx, *desc_rx;
unsigned long transfer_timeout; unsigned long transfer_timeout;
unsigned long timeout; unsigned long timeout;
struct spi_controller *controller = spi_imx->bitbang.master; struct spi_controller *controller = spi_imx->controller;
struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg; struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg;
struct scatterlist *last_sg = sg_last(rx->sgl, rx->nents); struct scatterlist *last_sg = sg_last(rx->sgl, rx->nents);
unsigned int bytes_per_word, i; unsigned int bytes_per_word, i;
...@@ -1450,7 +1449,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, ...@@ -1450,7 +1449,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
return -ETIMEDOUT; return -ETIMEDOUT;
} }
return transfer->len; return 0;
/* fallback to pio */ /* fallback to pio */
dma_failure_no_start: dma_failure_no_start:
transfer->error |= SPI_TRANS_FAIL_NO_START; transfer->error |= SPI_TRANS_FAIL_NO_START;
...@@ -1486,14 +1485,14 @@ static int spi_imx_pio_transfer(struct spi_device *spi, ...@@ -1486,14 +1485,14 @@ static int spi_imx_pio_transfer(struct spi_device *spi,
return -ETIMEDOUT; return -ETIMEDOUT;
} }
return transfer->len; return 0;
} }
static int spi_imx_pio_transfer_slave(struct spi_device *spi, static int spi_imx_pio_transfer_slave(struct spi_device *spi,
struct spi_transfer *transfer) struct spi_transfer *transfer)
{ {
struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller); struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller);
int ret = transfer->len; int ret = 0;
if (is_imx53_ecspi(spi_imx) && if (is_imx53_ecspi(spi_imx) &&
transfer->len > MX53_MAX_TRANSFER_BYTES) { transfer->len > MX53_MAX_TRANSFER_BYTES) {
...@@ -1533,11 +1532,13 @@ static int spi_imx_pio_transfer_slave(struct spi_device *spi, ...@@ -1533,11 +1532,13 @@ static int spi_imx_pio_transfer_slave(struct spi_device *spi,
return ret; return ret;
} }
static int spi_imx_transfer(struct spi_device *spi, static int spi_imx_transfer_one(struct spi_controller *controller,
struct spi_device *spi,
struct spi_transfer *transfer) struct spi_transfer *transfer)
{ {
struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller); struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller);
spi_imx_setupxfer(spi, transfer);
transfer->effective_speed_hz = spi_imx->spi_bus_clk; transfer->effective_speed_hz = spi_imx->spi_bus_clk;
/* flush rxfifo before transfer */ /* flush rxfifo before transfer */
...@@ -1642,7 +1643,7 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -1642,7 +1643,7 @@ static int spi_imx_probe(struct platform_device *pdev)
controller->use_gpio_descriptors = true; controller->use_gpio_descriptors = true;
spi_imx = spi_controller_get_devdata(controller); spi_imx = spi_controller_get_devdata(controller);
spi_imx->bitbang.master = controller; spi_imx->controller = controller;
spi_imx->dev = &pdev->dev; spi_imx->dev = &pdev->dev;
spi_imx->slave_mode = slave_mode; spi_imx->slave_mode = slave_mode;
...@@ -1659,20 +1660,20 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -1659,20 +1660,20 @@ static int spi_imx_probe(struct platform_device *pdev)
else else
controller->num_chipselect = 3; controller->num_chipselect = 3;
spi_imx->bitbang.setup_transfer = spi_imx_setupxfer; spi_imx->controller->transfer_one = spi_imx_transfer_one;
spi_imx->bitbang.txrx_bufs = spi_imx_transfer; spi_imx->controller->setup = spi_imx_setup;
spi_imx->bitbang.master->setup = spi_imx_setup; spi_imx->controller->cleanup = spi_imx_cleanup;
spi_imx->bitbang.master->cleanup = spi_imx_cleanup; spi_imx->controller->prepare_message = spi_imx_prepare_message;
spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; spi_imx->controller->unprepare_message = spi_imx_unprepare_message;
spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message; spi_imx->controller->slave_abort = spi_imx_slave_abort;
spi_imx->bitbang.master->slave_abort = spi_imx_slave_abort; spi_imx->controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS;
spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS;
if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx) || if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx) ||
is_imx53_ecspi(spi_imx)) is_imx53_ecspi(spi_imx))
spi_imx->bitbang.master->mode_bits |= SPI_LOOP | SPI_READY; spi_imx->controller->mode_bits |= SPI_LOOP | SPI_READY;
if (is_imx51_ecspi(spi_imx) || is_imx53_ecspi(spi_imx)) if (is_imx51_ecspi(spi_imx) || is_imx53_ecspi(spi_imx))
spi_imx->bitbang.master->mode_bits |= SPI_RX_CPHA_FLIP; spi_imx->controller->mode_bits |= SPI_RX_CPHA_FLIP;
if (is_imx51_ecspi(spi_imx) && if (is_imx51_ecspi(spi_imx) &&
device_property_read_u32(&pdev->dev, "cs-gpios", NULL)) device_property_read_u32(&pdev->dev, "cs-gpios", NULL))
...@@ -1681,7 +1682,7 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -1681,7 +1682,7 @@ static int spi_imx_probe(struct platform_device *pdev)
* setting the burst length to the word size. This is * setting the burst length to the word size. This is
* considerably faster than manually controlling the CS. * considerably faster than manually controlling the CS.
*/ */
spi_imx->bitbang.master->mode_bits |= SPI_CS_WORD; spi_imx->controller->mode_bits |= SPI_CS_WORD;
spi_imx->spi_drctl = spi_drctl; spi_imx->spi_drctl = spi_drctl;
...@@ -1754,10 +1755,10 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -1754,10 +1755,10 @@ static int spi_imx_probe(struct platform_device *pdev)
spi_imx->devtype_data->intctrl(spi_imx, 0); spi_imx->devtype_data->intctrl(spi_imx, 0);
controller->dev.of_node = pdev->dev.of_node; controller->dev.of_node = pdev->dev.of_node;
ret = spi_bitbang_start(&spi_imx->bitbang); ret = spi_register_controller(controller);
if (ret) { if (ret) {
dev_err_probe(&pdev->dev, ret, "bitbang start failed\n"); dev_err_probe(&pdev->dev, ret, "register controller failed\n");
goto out_bitbang_start; goto out_register_controller;
} }
pm_runtime_mark_last_busy(spi_imx->dev); pm_runtime_mark_last_busy(spi_imx->dev);
...@@ -1765,7 +1766,7 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -1765,7 +1766,7 @@ static int spi_imx_probe(struct platform_device *pdev)
return ret; return ret;
out_bitbang_start: out_register_controller:
if (spi_imx->devtype_data->has_dmamode) if (spi_imx->devtype_data->has_dmamode)
spi_imx_sdma_exit(spi_imx); spi_imx_sdma_exit(spi_imx);
out_runtime_pm_put: out_runtime_pm_put:
...@@ -1788,7 +1789,7 @@ static int spi_imx_remove(struct platform_device *pdev) ...@@ -1788,7 +1789,7 @@ static int spi_imx_remove(struct platform_device *pdev)
struct spi_imx_data *spi_imx = spi_controller_get_devdata(controller); struct spi_imx_data *spi_imx = spi_controller_get_devdata(controller);
int ret; int ret;
spi_bitbang_stop(&spi_imx->bitbang); spi_unregister_controller(controller);
ret = pm_runtime_resume_and_get(spi_imx->dev); ret = pm_runtime_resume_and_get(spi_imx->dev);
if (ret < 0) { if (ret < 0) {
...@@ -1803,7 +1804,6 @@ static int spi_imx_remove(struct platform_device *pdev) ...@@ -1803,7 +1804,6 @@ static int spi_imx_remove(struct platform_device *pdev)
pm_runtime_disable(spi_imx->dev); pm_runtime_disable(spi_imx->dev);
spi_imx_sdma_exit(spi_imx); spi_imx_sdma_exit(spi_imx);
spi_controller_put(controller);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment