Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40d755d8 authored by Joonwoo Park's avatar Joonwoo Park Committed by Stephen Boyd
Browse files

ASoC: wcd9xxx: reinitialize codec irq after subsystem restart



During subsystem restart, it's possible codec's upstream irq is disabled
if irq handler tried to access codec register when it's inaccessible.
Reinitialize codec irq handler after subsystem restart to be able to
bring codec interrupts back to work again.

CRs-fixed: 520754
Change-Id: Iaa6fa8da25cdf6ed6746754385ad895db8dcea9a
Signed-off-by: default avatarJoonwoo Park <joonwoop@codeaurora.org>
parent 67276156
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -490,6 +490,13 @@ static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx)
		dev_err(wcd9xxx->dev, "Failed to add children: %d\n", ret);
		goto err_irq;
	}

	ret = device_init_wakeup(wcd9xxx->dev, true);
	if (ret) {
		dev_err(wcd9xxx->dev, "Device wakeup init failed: %d\n", ret);
		goto err_irq;
	}

	return ret;
err_irq:
	wcd9xxx_irq_exit(wcd9xxx);
@@ -504,6 +511,7 @@ err:

static void wcd9xxx_device_exit(struct wcd9xxx *wcd9xxx)
{
	device_init_wakeup(wcd9xxx->dev, false);
	wcd9xxx_irq_exit(wcd9xxx);
	wcd9xxx_bring_down(wcd9xxx);
	wcd9xxx_free_reset(wcd9xxx);
@@ -1567,8 +1575,13 @@ static int wcd9xxx_device_up(struct wcd9xxx *wcd9xxx)
		pr_err("%s: Resetting Codec failed\n", __func__);

	wcd9xxx_bring_up(wcd9xxx);
	ret = wcd9xxx_irq_init(wcd9xxx);
	if (ret) {
		pr_err("%s: wcd9xx_irq_init failed : %d\n", __func__, ret);
	} else {
		if (wcd9xxx->post_reset)
		wcd9xxx->post_reset(wcd9xxx);
			ret = wcd9xxx->post_reset(wcd9xxx);
	}
	return ret;
}

@@ -1583,6 +1596,7 @@ static int wcd9xxx_slim_device_down(struct slim_device *sldev)
{
	struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);

	wcd9xxx_irq_exit(wcd9xxx);
	if (wcd9xxx->dev_down)
		wcd9xxx->dev_down(wcd9xxx);
	dev_dbg(wcd9xxx->dev, "%s: device down\n", __func__);
+3 −9
Original line number Diff line number Diff line
@@ -442,14 +442,7 @@ int wcd9xxx_irq_init(struct wcd9xxx *wcd9xxx)
			wcd9xxx->irq, ret);
	else {
		ret = enable_irq_wake(wcd9xxx->irq);
		if (ret == 0) {
			ret = device_init_wakeup(wcd9xxx->dev, 1);
			if (ret) {
				dev_err(wcd9xxx->dev, "Failed to init device"
					"wakeup : %d\n", ret);
				disable_irq_wake(wcd9xxx->irq);
			}
		} else
		if (ret)
			dev_err(wcd9xxx->dev, "Failed to set wake interrupt on"
				" IRQ %d: %d\n", wcd9xxx->irq, ret);
		if (ret)
@@ -489,12 +482,13 @@ int wcd9xxx_request_irq(struct wcd9xxx *wcd9xxx, int irq, irq_handler_t handler,

void wcd9xxx_irq_exit(struct wcd9xxx *wcd9xxx)
{
	dev_dbg(wcd9xxx->dev, "%s: Cleaning up irq %d\n", __func__,
		wcd9xxx->irq);
	if (wcd9xxx->irq) {
		disable_irq_wake(wcd9xxx->irq);
		free_irq(wcd9xxx->irq, wcd9xxx);
		/* Release parent's of node */
		wcd9xxx_irq_put_upstream_irq(wcd9xxx);
		device_init_wakeup(wcd9xxx->dev, 0);
	}
	mutex_destroy(&wcd9xxx->irq_lock);
	mutex_destroy(&wcd9xxx->nested_irq_lock);
+0 −2
Original line number Diff line number Diff line
@@ -193,8 +193,6 @@ struct wcd9xxx {

	void *ssr_priv;
	bool slim_device_bootup;
	/* device down flag by device_down notification */
	bool device_down;

	u32 num_of_supplies;
	struct regulator_bulk_data *supplies;
+6 −0
Original line number Diff line number Diff line
@@ -4789,6 +4789,12 @@ static int tapan_post_reset_cb(struct wcd9xxx *wcd9xxx)
		pr_err("%s: mbhc init failed %d\n", __func__, ret);
	else
		wcd9xxx_mbhc_start(&tapan->mbhc, tapan->mbhc.mbhc_cfg);

	tapan_cleanup_irqs(tapan);
	ret = tapan_setup_irqs(tapan);
	if (ret)
		pr_err("%s: Failed to setup irq: %d\n", __func__, ret);

	mutex_unlock(&codec->mutex);
	return ret;
}
+5 −0
Original line number Diff line number Diff line
@@ -6280,6 +6280,11 @@ static int taiko_post_reset_cb(struct wcd9xxx *wcd9xxx)
	}
	taiko->machine_codec_event_cb(codec, WCD9XXX_CODEC_EVENT_CODEC_UP);

	taiko_cleanup_irqs(taiko);
	ret = taiko_setup_irqs(taiko);
	if (ret)
		pr_err("%s: Failed to setup irq: %d\n", __func__, ret);

	mutex_unlock(&codec->mutex);
	return ret;
}