diff --git a/arch/arm/src/cxd56xx/cxd56_spi.c b/arch/arm/src/cxd56xx/cxd56_spi.c index 5a648ed21ad..f537e603e7e 100644 --- a/arch/arm/src/cxd56xx/cxd56_spi.c +++ b/arch/arm/src/cxd56xx/cxd56_spi.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -327,6 +328,11 @@ static struct cxd56_spidev_s g_spi3dev = }; #endif +/* Inhibit clock change */ + +static struct pm_cpu_freqlock_s g_hold_lock = + PM_CPUFREQLOCK_INIT(0, PM_CPUFREQLOCK_FLAG_HOLD); + /**************************************************************************** * Public Data ****************************************************************************/ @@ -643,6 +649,10 @@ static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd) register uint32_t regval; register uint32_t cr1val = 0; + /* Prohibit the clock change during SPI transfer */ + + up_pm_acquire_freqlock(&g_hold_lock); + /* Disable clock gating (clock enable) */ cxd56_spi_clock_gate_disable(priv->port); @@ -683,6 +693,10 @@ static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd) cxd56_spi_clock_gate_enable(priv->port); + /* Allow the clock change after SPI transfer */ + + up_pm_release_freqlock(&g_hold_lock); + return regval; } @@ -737,6 +751,10 @@ static void spi_do_exchange(FAR struct spi_dev_s *dev, tx.pv = txbuffer; rx.pv = rxbuffer; + /* Prohibit the clock change during SPI transfer */ + + up_pm_acquire_freqlock(&g_hold_lock); + /* Disable clock gating (clock enable) */ cxd56_spi_clock_gate_disable(priv->port); @@ -811,6 +829,10 @@ static void spi_do_exchange(FAR struct spi_dev_s *dev, /* Enable clock gating (clock disable) */ cxd56_spi_clock_gate_enable(priv->port); + + /* Allow the clock change after SPI transfer */ + + up_pm_release_freqlock(&g_hold_lock); } /**************************************************************************** @@ -1350,6 +1372,10 @@ void spi_flush(FAR struct spi_dev_s *dev) FAR struct cxd56_spidev_s *priv = (FAR struct cxd56_spidev_s *)dev; uint32_t regval = 0; + /* Prohibit the clock change during SPI transfer */ + + up_pm_acquire_freqlock(&g_hold_lock); + /* Disable clock gating (clock enable) */ cxd56_spi_clock_gate_disable(priv->port); @@ -1393,6 +1419,10 @@ void spi_flush(FAR struct spi_dev_s *dev) /* Enable clock gating (clock disable) */ cxd56_spi_clock_gate_enable(priv->port); + + /* Allow the clock change after SPI transfer */ + + up_pm_release_freqlock(&g_hold_lock); } #ifdef CONFIG_CXD56_DMAC @@ -1414,6 +1444,10 @@ static void spi_dmaexchange(FAR struct spi_dev_s *dev, DEBUGASSERT(priv && priv->spibase); + /* Prohibit the clock change during SPI transfer */ + + up_pm_acquire_freqlock(&g_hold_lock); + /* Disable clock gating (clock enable) */ cxd56_spi_clock_gate_disable(priv->port); @@ -1450,6 +1484,10 @@ static void spi_dmaexchange(FAR struct spi_dev_s *dev, /* Enable clock gating (clock disable) */ cxd56_spi_clock_gate_enable(priv->port); + + /* Allow the clock change after SPI transfer */ + + up_pm_release_freqlock(&g_hold_lock); } #ifndef CONFIG_SPI_EXCHANGE