diff options
author | Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> | 2016-01-18 17:27:21 +0100 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2016-02-05 20:25:22 -0500 |
commit | bcb2e2e45c372569b3711c3243d72b857ea48011 (patch) | |
tree | 79f8d48b9e9b2a8d24227768dec6ff613697d4a4 /drivers/spi | |
parent | 6021c64844b97c42767b6c1c96d575e66bd1b560 (diff) |
spi: dw: Rework the logic on testing/setting controller's readyness
Controller should not be enabled while configuring or setting up a
transfer call. It's enabled once the transfer call is ready to proceed,
and disabled once the last interrupt has be raised.
Change-Id: Ib9125a3600971b57e642730682f2b3bfb91b1e02
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi_dw.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index 2de97c0fd..bac7d5a9b 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -112,6 +112,7 @@ DEFINE_MM_REG_READ(ssi_comp_version, DW_SPI_REG_SSI_COMP_VERSION, 32) DEFINE_SET_BIT_OP(ssienr, DW_SPI_REG_SSIENR, DW_SPI_SSIENR_SSIEN_BIT) DEFINE_CLEAR_BIT_OP(ssienr, DW_SPI_REG_SSIENR, DW_SPI_SSIENR_SSIEN_BIT) +DEFINE_TEST_BIT_OP(ssienr, DW_SPI_REG_SSIENR, DW_SPI_SSIENR_SSIEN_BIT) DEFINE_TEST_BIT_OP(sr_busy, DW_SPI_REG_SR, DW_SPI_SR_BUSY_BIT) DEFINE_TEST_BIT_OP(icr, DW_SPI_REG_ICR, DW_SPI_SR_ICR_BIT) @@ -215,6 +216,8 @@ static void completed(struct device *dev, int error) /* Disabling interrupts */ write_imr(DW_SPI_IMR_MASK, info->regs); + /* Disabling the controller */ + clear_bit_ssienr(info->regs); _spi_control_cs(dev, 0); synchronous_call_complete(&spi->sync); @@ -315,6 +318,17 @@ static void pull_data(struct device *dev) DBG("Pulled: %d\n", cnt); } +static inline bool _spi_dw_is_controller_ready(struct device *dev) +{ + struct spi_dw_config *info = dev->config->config_info; + + if (test_bit_ssienr(info->regs) || test_bit_sr_busy(info->regs)) { + return false; + } + + return true; +} + static int spi_dw_configure(struct device *dev, struct spi_config *config) { @@ -327,14 +341,11 @@ static int spi_dw_configure(struct device *dev, DBG("spi_dw_configure: %p (0x%x), %p\n", dev, info->regs, config); /* Check status */ - if (test_bit_sr_busy(info->regs)) { - DBG("spi_dw_read: %Controller is busy\n"); + if (!_spi_dw_is_controller_ready(dev)) { + DBG("spi_dw_configure: Controller is busy\n"); return DEV_USED; } - /* Disable the controller, to be able to set it up */ - clear_bit_ssienr(info->regs); - /* Word size */ ctrlr0 |= DW_SPI_CTRLR0_DFS(SPI_WORD_SIZE_GET(flags)); @@ -367,9 +378,6 @@ static int spi_dw_configure(struct device *dev, /* Mask SPI interrupts */ write_imr(DW_SPI_IMR_MASK, info->regs); - /* Enable the controller */ - set_bit_ssienr(info->regs); - return DEV_OK; } @@ -398,14 +406,11 @@ static int spi_dw_transceive(struct device *dev, dev, tx_buf, tx_buf_len, rx_buf, rx_buf_len); /* Check status */ - if (test_bit_sr_busy(info->regs)) { - DBG("spi_dw_transceive: %Controller is busy\n"); + if (!_spi_dw_is_controller_ready(dev)) { + DBG("spi_dw_transceive: Controller is busy\n"); return DEV_USED; } - /* Disable the controller */ - clear_bit_ssienr(info->regs); - /* Set buffers info */ spi->tx_buf = tx_buf; spi->tx_buf_len = tx_buf_len/spi->dfs; @@ -449,7 +454,6 @@ static int spi_dw_suspend(struct device *dev) DBG("spi_dw_suspend: %p\n", dev); write_imr(DW_SPI_IMR_MASK, info->regs); - clear_bit_ssienr(info->regs); irq_disable(info->irq); _clock_off(dev); @@ -466,7 +470,6 @@ static int spi_dw_resume(struct device *dev) _clock_on(dev); irq_enable(info->irq); - set_bit_ssienr(info->regs); write_imr(DW_SPI_IMR_UNMASK, info->regs); return DEV_OK; |