From eb8519c0afe518391846332d389b4f9cfd13804f Mon Sep 17 00:00:00 2001 From: Yeleswarapu Nagaradhesh Date: Wed, 22 Jun 2016 00:20:06 +0530 Subject: [PATCH] drivers: mfd: do not modify reset gpio if codec is identified If target can support multiple codecs, only one of the codecs will be enumerated. Do not clean up common resources when other codec fails to enumerate. CRs-Fixed: 1041199 Change-Id: I74a298739925b5763458c2e637372aa8f2c2aa55 Signed-off-by: Yeleswarapu Nagaradhesh --- drivers/mfd/msm-cdc-pinctrl.c | 34 +++++++++++++++++++++++++++++ drivers/mfd/msm-cdc-supply.c | 5 ++--- drivers/mfd/wcd9xxx-core.c | 1 + drivers/mfd/wcd9xxx-utils.c | 12 ++++++++++ include/linux/mfd/msm-cdc-pinctrl.h | 6 +++++ include/linux/mfd/wcd9xxx/core.h | 1 + 6 files changed, 56 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/msm-cdc-pinctrl.c b/drivers/mfd/msm-cdc-pinctrl.c index a19e3a536950..3ffd20245877 100644 --- a/drivers/mfd/msm-cdc-pinctrl.c +++ b/drivers/mfd/msm-cdc-pinctrl.c @@ -25,6 +25,7 @@ struct msm_cdc_pinctrl_info { struct pinctrl *pinctrl; struct pinctrl_state *pinctrl_active; struct pinctrl_state *pinctrl_sleep; + int gpio; bool state; }; @@ -53,6 +54,28 @@ static struct msm_cdc_pinctrl_info *msm_cdc_pinctrl_get_gpiodata( return gpio_data; } +/* + * msm_cdc_get_gpio_state: select pinctrl sleep state + * @np: pointer to struct device_node + * + * Returns error code for failure and GPIO value on success + */ +int msm_cdc_get_gpio_state(struct device_node *np) +{ + struct msm_cdc_pinctrl_info *gpio_data; + int value = -EINVAL; + + gpio_data = msm_cdc_pinctrl_get_gpiodata(np); + if (!gpio_data) + return value; + + if (gpio_is_valid(gpio_data->gpio)) + value = gpio_get_value_cansleep(gpio_data->gpio); + + return value; +} +EXPORT_SYMBOL(msm_cdc_get_gpio_state); + /* * msm_cdc_pinctrl_select_sleep_state: select pinctrl sleep state * @np: pointer to struct device_node @@ -165,6 +188,17 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s: set cdc gpio sleep state fail: %d\n", __func__, ret); + gpio_data->gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,cdc-rst-n-gpio", 0); + if (gpio_is_valid(gpio_data->gpio)) { + ret = gpio_request(gpio_data->gpio, "MSM_CDC_RESET"); + if (ret) { + dev_err(&pdev->dev, "%s: Failed to request gpio %d\n", + __func__, gpio_data->gpio); + goto err_lookup_state; + } + } + dev_set_drvdata(&pdev->dev, gpio_data); return 0; diff --git a/drivers/mfd/msm-cdc-supply.c b/drivers/mfd/msm-cdc-supply.c index d553f7b3f492..bfb19de8ce89 100644 --- a/drivers/mfd/msm-cdc-supply.c +++ b/drivers/mfd/msm-cdc-supply.c @@ -202,7 +202,6 @@ int msm_cdc_release_supplies(struct device *dev, msm_cdc_disable_static_supplies(dev, supplies, cdc_vreg, num_supplies); - for (i = 0; i < num_supplies; i++) { if (regulator_count_voltages(supplies[i].consumer) < 0) continue; @@ -210,9 +209,9 @@ int msm_cdc_release_supplies(struct device *dev, regulator_set_voltage(supplies[i].consumer, 0, cdc_vreg[i].max_uV); regulator_set_load(supplies[i].consumer, 0); + devm_regulator_put(supplies[i].consumer); + supplies[i].consumer = NULL; } - - regulator_bulk_free(num_supplies, supplies); devm_kfree(dev, supplies); return rc; diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c index 555fac10377f..a32a20e19567 100644 --- a/drivers/mfd/wcd9xxx-core.c +++ b/drivers/mfd/wcd9xxx-core.c @@ -1507,6 +1507,7 @@ static int wcd9xxx_slim_device_down(struct slim_device *sldev) wcd9xxx_irq_exit(&wcd9xxx->core_res); if (wcd9xxx->dev_down) wcd9xxx->dev_down(wcd9xxx); + wcd9xxx_reset_low(wcd9xxx->dev); return 0; } diff --git a/drivers/mfd/wcd9xxx-utils.c b/drivers/mfd/wcd9xxx-utils.c index 6bfe3d5a1788..52346b551481 100644 --- a/drivers/mfd/wcd9xxx-utils.c +++ b/drivers/mfd/wcd9xxx-utils.c @@ -618,6 +618,7 @@ int wcd9xxx_reset(struct device *dev) { struct wcd9xxx *wcd9xxx; int rc; + int value; if (!dev) return -ENODEV; @@ -632,6 +633,12 @@ int wcd9xxx_reset(struct device *dev) return -EINVAL; } + value = msm_cdc_get_gpio_state(wcd9xxx->wcd_rst_np); + if (value > 0) { + wcd9xxx->avoid_cdc_rstlow = 1; + return 0; + } + rc = msm_cdc_pinctrl_select_sleep_state(wcd9xxx->wcd_rst_np); if (rc) { dev_err(dev, "%s: wcd sleep state request fail!\n", @@ -679,6 +686,11 @@ int wcd9xxx_reset_low(struct device *dev) __func__); return -EINVAL; } + if (wcd9xxx->avoid_cdc_rstlow) { + wcd9xxx->avoid_cdc_rstlow = 0; + dev_dbg(dev, "%s: avoid pull down of reset GPIO\n", __func__); + return 0; + } rc = msm_cdc_pinctrl_select_sleep_state(wcd9xxx->wcd_rst_np); if (rc) diff --git a/include/linux/mfd/msm-cdc-pinctrl.h b/include/linux/mfd/msm-cdc-pinctrl.h index 395b935b6aec..951b8d4d1ed9 100644 --- a/include/linux/mfd/msm-cdc-pinctrl.h +++ b/include/linux/mfd/msm-cdc-pinctrl.h @@ -20,6 +20,7 @@ extern int msm_cdc_pinctrl_select_sleep_state(struct device_node *); extern int msm_cdc_pinctrl_select_active_state(struct device_node *); extern bool msm_cdc_pinctrl_get_state(struct device_node *); +extern int msm_cdc_get_gpio_state(struct device_node *); #else int msm_cdc_pinctrl_select_sleep_state(struct device_node *np) @@ -30,6 +31,11 @@ int msm_cdc_pinctrl_select_active_state(struct device_node *np) { return 0; } +int msm_cdc_get_gpio_state(struct device_node *np) +{ + return 0; +} +# #endif #endif diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h index 96937a4338a8..c56ad3afcd46 100644 --- a/include/linux/mfd/wcd9xxx/core.h +++ b/include/linux/mfd/wcd9xxx/core.h @@ -328,6 +328,7 @@ struct wcd9xxx { struct wcd9xxx_codec_type *codec_type; bool prev_pg_valid; u8 prev_pg; + u8 avoid_cdc_rstlow; struct wcd9xxx_power_region *wcd9xxx_pwr[WCD9XXX_MAX_PWR_REGIONS]; };