ASoC: tegra: call pm_runtime APIs around register accesses
authorStephen Warren <swarren@nvidia.com>
Fri, 15 Nov 2013 18:29:45 +0000 (11:29 -0700)
committerStephen Warren <swarren@nvidia.com>
Wed, 11 Dec 2013 23:43:44 +0000 (16:43 -0700)
Call pm_runtime_get_sync() before all register accesses; the HW requires
clocks to be running when accessing registers.

This hasn't been needed to date, since all register IO was performed
while playback was active, and hence the ASoC core had already called
pm_runtime_get(). However, an imminent future commit will allocate and
set up the FIFOs and routing during probe(), when that "protection"
won't be in place.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Mark Brown <broonie@linaro.org>
sound/soc/tegra/tegra30_ahub.c

index 38c6962b7d66ba9ebf8b181b76361b3970f49d41..7d146e6b7038fec38bbffc1be85cfd2fca0fb898 100644 (file)
@@ -114,6 +114,8 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
                   (channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE);
        *reqsel = ahub->dma_sel + channel;
 
+       pm_runtime_get_sync(ahub->dev);
+
        reg = TEGRA30_AHUB_CHANNEL_CTRL +
              (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
        val = tegra30_apbif_read(reg);
@@ -140,6 +142,8 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
              (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
        ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
 
+       pm_runtime_put(ahub->dev);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo);
@@ -149,12 +153,16 @@ int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
        int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
        int reg, val;
 
+       pm_runtime_get_sync(ahub->dev);
+
        reg = TEGRA30_AHUB_CHANNEL_CTRL +
              (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
        val = tegra30_apbif_read(reg);
        val |= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
        tegra30_apbif_write(reg, val);
 
+       pm_runtime_put(ahub->dev);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo);
@@ -164,12 +172,16 @@ int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
        int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
        int reg, val;
 
+       pm_runtime_get_sync(ahub->dev);
+
        reg = TEGRA30_AHUB_CHANNEL_CTRL +
              (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
        val = tegra30_apbif_read(reg);
        val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
        tegra30_apbif_write(reg, val);
 
+       pm_runtime_put(ahub->dev);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo);
@@ -204,6 +216,8 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
                   (channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE);
        *reqsel = ahub->dma_sel + channel;
 
+       pm_runtime_get_sync(ahub->dev);
+
        reg = TEGRA30_AHUB_CHANNEL_CTRL +
              (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
        val = tegra30_apbif_read(reg);
@@ -230,6 +244,8 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
              (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
        ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
 
+       pm_runtime_put(ahub->dev);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo);
@@ -239,12 +255,16 @@ int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif)
        int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
        int reg, val;
 
+       pm_runtime_get_sync(ahub->dev);
+
        reg = TEGRA30_AHUB_CHANNEL_CTRL +
              (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
        val = tegra30_apbif_read(reg);
        val |= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
        tegra30_apbif_write(reg, val);
 
+       pm_runtime_put(ahub->dev);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo);
@@ -254,12 +274,16 @@ int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif)
        int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
        int reg, val;
 
+       pm_runtime_get_sync(ahub->dev);
+
        reg = TEGRA30_AHUB_CHANNEL_CTRL +
              (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
        val = tegra30_apbif_read(reg);
        val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
        tegra30_apbif_write(reg, val);
 
+       pm_runtime_put(ahub->dev);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo);
@@ -280,10 +304,14 @@ int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
        int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
        int reg;
 
+       pm_runtime_get_sync(ahub->dev);
+
        reg = TEGRA30_AHUB_AUDIO_RX +
              (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
        tegra30_audio_write(reg, 1 << txcif);
 
+       pm_runtime_put(ahub->dev);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_source);
@@ -293,10 +321,14 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif)
        int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
        int reg;
 
+       pm_runtime_get_sync(ahub->dev);
+
        reg = TEGRA30_AHUB_AUDIO_RX +
              (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
        tegra30_audio_write(reg, 0);
 
+       pm_runtime_put(ahub->dev);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source);