summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBanajit Goswami <bgoswami@codeaurora.org>2015-10-27 23:51:49 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:16:50 -0700
commit1f1fb7752f74dafe246a0f0027d4b223ebc4e99a (patch)
treec9812637aa4028932653a2d94d21bcc5fa4bfeef
parent75a73e973ce3bbfaf854d5f2612aa23f07a1bb2d (diff)
mfd: wcd9xxx: avoid slimbus read/write during ADSP reset
During ADSP subsystem restart, all slimbus read/write would fail as the bus is not available. Avoid codec read/write, until the slimbus master in ADSP is up. Change-Id: Iec1933d2625c1cd3dd700b2b3e2ffc7eae64880b Signed-off-by: Banajit Goswami <bgoswami@codeaurora.org>
-rw-r--r--drivers/mfd/wcd9xxx-core.c60
-rwxr-xr-xinclude/linux/mfd/wcd9xxx/core.h4
2 files changed, 50 insertions, 14 deletions
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index c2ee8979e50a..34ff798bf497 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -706,6 +706,13 @@ static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg,
msg.num_bytes = bytes;
msg.comp = NULL;
+ if (!wcd9xxx->dev_up) {
+ dev_dbg_ratelimited(
+ wcd9xxx->dev, "%s: No read allowed. dev_up = %d\n",
+ __func__, wcd9xxx->dev_up);
+ return 0;
+ }
+
while (1) {
mutex_lock(&wcd9xxx->xfer_lock);
ret = slim_request_val_element(interface ?
@@ -760,6 +767,13 @@ static int __wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx,
return -EINVAL;
}
+ if (!wcd9xxx->dev_up) {
+ dev_dbg_ratelimited(
+ wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n",
+ __func__, wcd9xxx->dev_up);
+ return 0;
+ }
+
while (bytes_to_write > 0) {
bytes_allowed = wcd9xxx_slim_get_allowed_slice(wcd9xxx,
bytes_to_write);
@@ -853,6 +867,13 @@ static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx,
msg.num_bytes = bytes;
msg.comp = NULL;
+ if (!wcd9xxx->dev_up) {
+ dev_dbg_ratelimited(
+ wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n",
+ __func__, wcd9xxx->dev_up);
+ return 0;
+ }
+
while (1) {
mutex_lock(&wcd9xxx->xfer_lock);
ret = slim_change_val_element(interface ?
@@ -893,6 +914,13 @@ int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx,
return -EINVAL;
}
+ if (!wcd9xxx->dev_up) {
+ dev_dbg_ratelimited(
+ wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n",
+ __func__, wcd9xxx->dev_up);
+ return 0;
+ }
+
msgs = kzalloc(size * (sizeof(struct slim_val_inf)), GFP_KERNEL);
if (!msgs) {
ret = -ENOMEM;
@@ -1144,7 +1172,7 @@ static int wcd9xxx_reset(struct wcd9xxx *wcd9xxx)
int ret;
struct wcd9xxx_pdata *pdata = wcd9xxx->dev->platform_data;
- if (wcd9xxx->reset_gpio && wcd9xxx->slim_device_bootup
+ if (wcd9xxx->reset_gpio && wcd9xxx->dev_up
&& !pdata->use_pinctrl) {
ret = gpio_request(wcd9xxx->reset_gpio, "CDC_RESET");
if (ret) {
@@ -2204,7 +2232,7 @@ static int wcd9xxx_i2c_probe(struct i2c_client *client,
dev_set_drvdata(&client->dev, wcd9xxx);
wcd9xxx->dev = &client->dev;
wcd9xxx->reset_gpio = pdata->reset_gpio;
- wcd9xxx->slim_device_bootup = true;
+ wcd9xxx->dev_up = true;
if (client->dev.of_node)
wcd9xxx->mclk_rate = pdata->mclk_rate;
@@ -2893,7 +2921,7 @@ static int wcd9xxx_slim_probe(struct slim_device *slim)
wcd9xxx->reset_gpio = pdata->reset_gpio;
wcd9xxx->dev = &slim->dev;
wcd9xxx->mclk_rate = pdata->mclk_rate;
- wcd9xxx->slim_device_bootup = true;
+ wcd9xxx->dev_up = true;
ret = extcodec_get_pinctrl(&slim->dev);
if (ret < 0)
@@ -3026,11 +3054,6 @@ static int wcd9xxx_device_up(struct wcd9xxx *wcd9xxx)
int ret = 0;
struct wcd9xxx_core_resource *wcd9xxx_res = &wcd9xxx->core_res;
- if (wcd9xxx->slim_device_bootup) {
- wcd9xxx->slim_device_bootup = false;
- return 0;
- }
-
dev_info(wcd9xxx->dev, "%s: codec bring up\n", __func__);
wcd9xxx_bring_up(wcd9xxx);
ret = wcd9xxx_irq_init(wcd9xxx_res);
@@ -3052,9 +3075,11 @@ static int wcd9xxx_slim_device_reset(struct slim_device *sldev)
return -EINVAL;
}
- dev_info(wcd9xxx->dev, "%s: device reset\n", __func__);
- if (wcd9xxx->slim_device_bootup)
+ dev_info(wcd9xxx->dev, "%s: device reset, dev_up = %d\n",
+ __func__, wcd9xxx->dev_up);
+ if (wcd9xxx->dev_up)
return 0;
+
ret = wcd9xxx_reset(wcd9xxx);
if (ret)
dev_err(wcd9xxx->dev, "%s: Resetting Codec failed\n", __func__);
@@ -3069,7 +3094,12 @@ static int wcd9xxx_slim_device_up(struct slim_device *sldev)
pr_err("%s: wcd9xxx is NULL\n", __func__);
return -EINVAL;
}
- dev_info(wcd9xxx->dev, "%s: slim device up\n", __func__);
+ dev_info(wcd9xxx->dev, "%s: slim device up, dev_up = %d\n",
+ __func__, wcd9xxx->dev_up);
+ if (wcd9xxx->dev_up)
+ return 0;
+
+ wcd9xxx->dev_up = true;
return wcd9xxx_device_up(wcd9xxx);
}
@@ -3081,10 +3111,16 @@ static int wcd9xxx_slim_device_down(struct slim_device *sldev)
pr_err("%s: wcd9xxx is NULL\n", __func__);
return -EINVAL;
}
+
+ dev_info(wcd9xxx->dev, "%s: device down, dev_up = %d\n",
+ __func__, wcd9xxx->dev_up);
+ if (!wcd9xxx->dev_up)
+ return 0;
+
+ wcd9xxx->dev_up = false;
wcd9xxx_irq_exit(&wcd9xxx->core_res);
if (wcd9xxx->dev_down)
wcd9xxx->dev_down(wcd9xxx);
- dev_dbg(wcd9xxx->dev, "%s: device down\n", __func__);
return 0;
}
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index af66a8ddfcf0..77ed7a86c60d 100755
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -269,7 +269,7 @@ struct wcd9xxx {
int (*post_reset)(struct wcd9xxx *wcd9xxx);
void *ssr_priv;
- bool slim_device_bootup;
+ bool dev_up;
u32 num_of_supplies;
struct regulator_bulk_data *supplies;