diff options
| -rw-r--r-- | drivers/spi/spi-sun6i.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 9918a57a6a6e..e3114832c485 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <linux/of_device.h> | ||
| 20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 21 | #include <linux/pm_runtime.h> | 22 | #include <linux/pm_runtime.h> |
| 22 | #include <linux/reset.h> | 23 | #include <linux/reset.h> |
| @@ -24,6 +25,7 @@ | |||
| 24 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
| 25 | 26 | ||
| 26 | #define SUN6I_FIFO_DEPTH 128 | 27 | #define SUN6I_FIFO_DEPTH 128 |
| 28 | #define SUN8I_FIFO_DEPTH 64 | ||
| 27 | 29 | ||
| 28 | #define SUN6I_GBL_CTL_REG 0x04 | 30 | #define SUN6I_GBL_CTL_REG 0x04 |
| 29 | #define SUN6I_GBL_CTL_BUS_ENABLE BIT(0) | 31 | #define SUN6I_GBL_CTL_BUS_ENABLE BIT(0) |
| @@ -90,6 +92,7 @@ struct sun6i_spi { | |||
| 90 | const u8 *tx_buf; | 92 | const u8 *tx_buf; |
| 91 | u8 *rx_buf; | 93 | u8 *rx_buf; |
| 92 | int len; | 94 | int len; |
| 95 | unsigned long fifo_depth; | ||
| 93 | }; | 96 | }; |
| 94 | 97 | ||
| 95 | static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg) | 98 | static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg) |
| @@ -155,7 +158,9 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable) | |||
| 155 | 158 | ||
| 156 | static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) | 159 | static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) |
| 157 | { | 160 | { |
| 158 | return SUN6I_FIFO_DEPTH - 1; | 161 | struct sun6i_spi *sspi = spi_master_get_devdata(spi->master); |
| 162 | |||
| 163 | return sspi->fifo_depth - 1; | ||
| 159 | } | 164 | } |
| 160 | 165 | ||
| 161 | static int sun6i_spi_transfer_one(struct spi_master *master, | 166 | static int sun6i_spi_transfer_one(struct spi_master *master, |
| @@ -170,7 +175,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, | |||
| 170 | u32 reg; | 175 | u32 reg; |
| 171 | 176 | ||
| 172 | /* We don't support transfer larger than the FIFO */ | 177 | /* We don't support transfer larger than the FIFO */ |
| 173 | if (tfr->len > SUN6I_FIFO_DEPTH) | 178 | if (tfr->len > sspi->fifo_depth) |
| 174 | return -EINVAL; | 179 | return -EINVAL; |
| 175 | 180 | ||
| 176 | reinit_completion(&sspi->done); | 181 | reinit_completion(&sspi->done); |
| @@ -265,7 +270,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, | |||
| 265 | SUN6I_BURST_CTL_CNT_STC(tx_len)); | 270 | SUN6I_BURST_CTL_CNT_STC(tx_len)); |
| 266 | 271 | ||
| 267 | /* Fill the TX FIFO */ | 272 | /* Fill the TX FIFO */ |
| 268 | sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH); | 273 | sun6i_spi_fill_fifo(sspi, sspi->fifo_depth); |
| 269 | 274 | ||
| 270 | /* Enable the interrupts */ | 275 | /* Enable the interrupts */ |
| 271 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC); | 276 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC); |
| @@ -288,7 +293,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, | |||
| 288 | goto out; | 293 | goto out; |
| 289 | } | 294 | } |
| 290 | 295 | ||
| 291 | sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH); | 296 | sun6i_spi_drain_fifo(sspi, sspi->fifo_depth); |
| 292 | 297 | ||
| 293 | out: | 298 | out: |
| 294 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); | 299 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); |
| @@ -398,6 +403,8 @@ static int sun6i_spi_probe(struct platform_device *pdev) | |||
| 398 | } | 403 | } |
| 399 | 404 | ||
| 400 | sspi->master = master; | 405 | sspi->master = master; |
| 406 | sspi->fifo_depth = (unsigned long)of_device_get_match_data(&pdev->dev); | ||
| 407 | |||
| 401 | master->max_speed_hz = 100 * 1000 * 1000; | 408 | master->max_speed_hz = 100 * 1000 * 1000; |
| 402 | master->min_speed_hz = 3 * 1000; | 409 | master->min_speed_hz = 3 * 1000; |
| 403 | master->set_cs = sun6i_spi_set_cs; | 410 | master->set_cs = sun6i_spi_set_cs; |
| @@ -470,7 +477,8 @@ static int sun6i_spi_remove(struct platform_device *pdev) | |||
| 470 | } | 477 | } |
| 471 | 478 | ||
| 472 | static const struct of_device_id sun6i_spi_match[] = { | 479 | static const struct of_device_id sun6i_spi_match[] = { |
| 473 | { .compatible = "allwinner,sun6i-a31-spi", }, | 480 | { .compatible = "allwinner,sun6i-a31-spi", .data = (void *)SUN6I_FIFO_DEPTH }, |
| 481 | { .compatible = "allwinner,sun8i-h3-spi", .data = (void *)SUN8I_FIFO_DEPTH }, | ||
| 474 | {} | 482 | {} |
| 475 | }; | 483 | }; |
| 476 | MODULE_DEVICE_TABLE(of, sun6i_spi_match); | 484 | MODULE_DEVICE_TABLE(of, sun6i_spi_match); |
