summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhalchandra Gajare <gajare@codeaurora.org>2016-10-06 12:01:24 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-11 15:31:46 -0700
commit93b43a172c65188fad17b3f46fa4014f285ca4ef (patch)
tree4e0686a5c0130ad0c73b36de24a2d13dd78a83f9
parentc5cfd3c491b6fafbdc7995e605b189c184f1f2a5 (diff)
ASoC: wcd-spi: Move one time initializations to component bind
One time initializations like regmap and debugfs init are currently done in the init function. But, in case of subsystem restart, the driver can get de-initialized and then initialized again. This causes the debugfs and regmap entries to get removed and added again during subsystem restart cases. Avoid this by moving all the one time initialization of the driver to component bind. Change-Id: Ideed297fde016b0623616be64875be094e688981 Signed-off-by: Bhalchandra Gajare <gajare@codeaurora.org>
-rw-r--r--sound/soc/codecs/wcd-spi.c83
1 files changed, 44 insertions, 39 deletions
diff --git a/sound/soc/codecs/wcd-spi.c b/sound/soc/codecs/wcd-spi.c
index 60efcb174740..2763073ed056 100644
--- a/sound/soc/codecs/wcd-spi.c
+++ b/sound/soc/codecs/wcd-spi.c
@@ -631,6 +631,14 @@ static int wcd_spi_init(struct spi_device *spi)
if (IS_ERR_VALUE(ret))
goto err_wr_en;
+ /*
+ * In case spi_init is called after component deinit,
+ * it is possible hardware register state is also reset.
+ * Sync the regcache here so hardware state is updated
+ * to reflect the cache.
+ */
+ regcache_sync(wcd_spi->regmap);
+
regmap_write(wcd_spi->regmap, WCD_SPI_SLAVE_CONFIG,
0x0F3D0800);
@@ -1093,46 +1101,12 @@ static struct regmap_config wcd_spi_regmap_cfg = {
static int wdsp_spi_init(struct device *dev, void *priv_data)
{
struct spi_device *spi = to_spi_device(dev);
- struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi);
int ret;
- wcd_spi->reg_bytes = DIV_ROUND_UP(wcd_spi_regmap_cfg.reg_bits, 8);
- wcd_spi->val_bytes = DIV_ROUND_UP(wcd_spi_regmap_cfg.val_bits, 8);
-
- wcd_spi->regmap = devm_regmap_init(&spi->dev, &wcd_spi_regmap_bus,
- &spi->dev, &wcd_spi_regmap_cfg);
- if (IS_ERR(wcd_spi->regmap)) {
- ret = PTR_ERR(wcd_spi->regmap);
- dev_err(&spi->dev, "%s: Failed to allocate regmap, err = %d\n",
- __func__, ret);
- goto err_regmap;
- }
-
- if (wcd_spi_debugfs_init(spi))
- dev_err(&spi->dev, "%s: Failed debugfs init\n", __func__);
-
- spi_message_init(&wcd_spi->msg1);
- spi_message_add_tail(&wcd_spi->xfer1, &wcd_spi->msg1);
-
- spi_message_init(&wcd_spi->msg2);
- spi_message_add_tail(&wcd_spi->xfer2[0], &wcd_spi->msg2);
- spi_message_add_tail(&wcd_spi->xfer2[1], &wcd_spi->msg2);
-
ret = wcd_spi_init(spi);
- if (IS_ERR_VALUE(ret)) {
+ if (IS_ERR_VALUE(ret))
dev_err(&spi->dev, "%s: Init failed, err = %d\n",
__func__, ret);
- goto err_init;
- }
-
- return 0;
-
-err_init:
- spi_transfer_del(&wcd_spi->xfer1);
- spi_transfer_del(&wcd_spi->xfer2[0]);
- spi_transfer_del(&wcd_spi->xfer2[1]);
-
-err_regmap:
return ret;
}
@@ -1141,9 +1115,11 @@ static int wdsp_spi_deinit(struct device *dev, void *priv_data)
struct spi_device *spi = to_spi_device(dev);
struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi);
- spi_transfer_del(&wcd_spi->xfer1);
- spi_transfer_del(&wcd_spi->xfer2[0]);
- spi_transfer_del(&wcd_spi->xfer2[1]);
+ /*
+ * Deinit means the hardware is reset. Mark the cache
+ * as dirty here, so init will sync the cache
+ */
+ regcache_mark_dirty(wcd_spi->regmap);
return 0;
}
@@ -1170,9 +1146,34 @@ static int wcd_spi_component_bind(struct device *dev,
ret = wcd_spi->m_ops->register_cmpnt_ops(master, dev,
wcd_spi,
&wdsp_spi_ops);
- if (ret)
+ if (ret) {
dev_err(dev, "%s: register_cmpnt_ops failed, err = %d\n",
__func__, ret);
+ goto done;
+ }
+
+ wcd_spi->reg_bytes = DIV_ROUND_UP(wcd_spi_regmap_cfg.reg_bits, 8);
+ wcd_spi->val_bytes = DIV_ROUND_UP(wcd_spi_regmap_cfg.val_bits, 8);
+
+ wcd_spi->regmap = devm_regmap_init(&spi->dev, &wcd_spi_regmap_bus,
+ &spi->dev, &wcd_spi_regmap_cfg);
+ if (IS_ERR(wcd_spi->regmap)) {
+ ret = PTR_ERR(wcd_spi->regmap);
+ dev_err(&spi->dev, "%s: Failed to allocate regmap, err = %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ if (wcd_spi_debugfs_init(spi))
+ dev_err(&spi->dev, "%s: Failed debugfs init\n", __func__);
+
+ spi_message_init(&wcd_spi->msg1);
+ spi_message_add_tail(&wcd_spi->xfer1, &wcd_spi->msg1);
+
+ spi_message_init(&wcd_spi->msg2);
+ spi_message_add_tail(&wcd_spi->xfer2[0], &wcd_spi->msg2);
+ spi_message_add_tail(&wcd_spi->xfer2[1], &wcd_spi->msg2);
+done:
return ret;
}
@@ -1185,6 +1186,10 @@ static void wcd_spi_component_unbind(struct device *dev,
wcd_spi->m_dev = NULL;
wcd_spi->m_ops = NULL;
+
+ spi_transfer_del(&wcd_spi->xfer1);
+ spi_transfer_del(&wcd_spi->xfer2[0]);
+ spi_transfer_del(&wcd_spi->xfer2[1]);
}
static const struct component_ops wcd_spi_component_ops = {