Эх сурвалжийг харах

Merge "dsp: add workqueue for audio_prm and pinctrl_lpi"

qctecmdr 3 жил өмнө
parent
commit
5fa13c2cd8
2 өөрчлөгдсөн 32 нэмэгдсэн , 20 устгасан
  1. 16 13
      dsp/audio_prm.c
  2. 16 7
      soc/pinctrl-lpi.c

+ 16 - 13
dsp/audio_prm.c

@@ -1,13 +1,6 @@
-/* Copyright (c) 2019-2020, 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -37,6 +30,7 @@ struct audio_prm {
 	atomic_t state;
 	atomic_t status;
 	bool is_adsp_up;
+	struct work_struct reset_work;
 };
 
 static struct audio_prm g_prm;
@@ -313,6 +307,13 @@ int audio_prm_set_lpass_clk_cfg (struct clk_cfg *clk, uint8_t enable)
 }
 EXPORT_SYMBOL(audio_prm_set_lpass_clk_cfg);
 
+static void audio_prm_adsp_work(struct work_struct *work)
+{
+	mutex_lock(&g_prm.lock);
+	g_prm.is_adsp_up = true;
+	mutex_unlock(&g_prm.lock);
+}
+
 static int audio_prm_service_cb(struct notifier_block *this,
 				unsigned long opcode, void *data)
 {
@@ -327,9 +328,7 @@ static int audio_prm_service_cb(struct notifier_block *this,
 		mutex_unlock(&g_prm.lock);
 		break;
 	case AUDIO_NOTIFIER_SERVICE_UP:
-		mutex_lock(&g_prm.lock);
-		g_prm.is_adsp_up = true;
-		mutex_unlock(&g_prm.lock);
+		schedule_work(&g_prm.reset_work);
 		break;
 	default:
 		break;
@@ -362,6 +361,7 @@ static int audio_prm_probe(struct gpr_device *adev)
 
 	init_waitqueue_head(&g_prm.wait);
 	g_prm.is_adsp_up = true;
+	INIT_WORK(&g_prm.reset_work, audio_prm_adsp_work);
 	pr_err("%s: prm probe success\n", __func__);
 	return ret;
 }
@@ -374,6 +374,9 @@ static int audio_prm_remove(struct gpr_device *adev)
 	mutex_lock(&g_prm.lock);
 	g_prm.is_adsp_up = false;
 	g_prm.adev = NULL;
+	flush_work(&g_prm.reset_work);
+	cancel_work_sync(&g_prm.reset_work);
+	INIT_WORK(&g_prm.reset_work, NULL);
 	mutex_unlock(&g_prm.lock);
 	return ret;
 }

+ 16 - 7
soc/pinctrl-lpi.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/gpio.h>
@@ -119,6 +119,7 @@ struct lpi_gpio_state {
 	struct mutex         slew_access_lock;
 	bool core_hw_vote_status;
 	struct mutex        core_hw_vote_lock;
+	struct work_struct reset_work;
 };
 
 static const char *const lpi_gpio_groups[] = {
@@ -471,6 +472,18 @@ static void lpi_gpio_set(struct gpio_chip *chip, unsigned int pin, int value)
 	lpi_config_set(state->ctrl, pin, &config, 1);
 }
 
+static void lpi_clk_reset(struct work_struct *work)
+{
+	struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev);
+
+	if (state->lpass_core_hw_vote)
+		digital_cdc_rsc_mgr_hw_vote_reset(
+			state->lpass_core_hw_vote);
+	if (state->lpass_audio_hw_vote)
+		digital_cdc_rsc_mgr_hw_vote_reset(
+			state->lpass_audio_hw_vote);
+}
+
 static int lpi_notifier_service_cb(struct notifier_block *this,
 				   unsigned long opcode, void *ptr)
 {
@@ -496,12 +509,7 @@ static int lpi_notifier_service_cb(struct notifier_block *this,
 		if (!lpi_dev_up) {
 			/* Add 100ms sleep to ensure AVS is up after SSR */
 			msleep(100);
-			if (state->lpass_core_hw_vote)
-				digital_cdc_rsc_mgr_hw_vote_reset(
-					state->lpass_core_hw_vote);
-			if (state->lpass_audio_hw_vote)
-				digital_cdc_rsc_mgr_hw_vote_reset(
-					state->lpass_audio_hw_vote);
+			schedule_work(&state->reset_work);
 		}
 
 		lpi_dev_up = true;
@@ -742,6 +750,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev)
 	}
 
 	state->base = lpi_base;
+	INIT_WORK(&state->reset_work, lpi_clk_reset);
 
 	for (i = 0; i < npins; i++, pindesc++) {
 		pad = &pads[i];