From be588ca11dcf2c0cca1a02c4c0a179f87eddc2ec Mon Sep 17 00:00:00 2001
From: Yuan Lin <yualin@google.com>
Date: Wed, 17 Aug 2016 10:03:11 -0700
Subject: [PATCH] ASoC: check for null function pointer for dummy device
 read/write

Adding check for null function pointer for dummy sound driver
read/write to prevent kernel panic.

Bug: 28838221
Change-Id: I32548a7e37869a17a5f88c646ddbfb8243cadcc0
Signed-off-by: Yuan Lin <yualin@google.com>
---
 sound/soc/soc-core.c | 36 ++++++++++++++++++++++--------------
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b6d808c06791..abcb4719632f 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2103,13 +2103,17 @@ unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
 {
 	unsigned int ret;
 
-	if (unlikely(!snd_card_is_online_state(codec->card->snd_card))) {
-		dev_err(codec->dev, "read 0x%02x while offline\n", reg);
-		return -ENODEV;
-	}
-	ret = codec->read(codec, reg);
-	dev_dbg(codec->dev, "read %x => %x\n", reg, ret);
-	trace_snd_soc_reg_read(codec, reg, ret);
+        if (codec->read) {
+		if (unlikely(!snd_card_is_online_state(codec->card->snd_card))) {
+			dev_err(codec->dev, "read 0x%02x while offline\n", reg);
+			return -ENODEV;
+		}
+		ret = codec->read(codec, reg);
+		dev_dbg(codec->dev, "read %x => %x\n", reg, ret);
+		trace_snd_soc_reg_read(codec, reg, ret);
+        }
+        else
+		ret = -EIO;
 
 	return ret;
 }
@@ -2118,13 +2122,17 @@ EXPORT_SYMBOL_GPL(snd_soc_read);
 unsigned int snd_soc_write(struct snd_soc_codec *codec,
 			   unsigned int reg, unsigned int val)
 {
-	if (unlikely(!snd_card_is_online_state(codec->card->snd_card))) {
-		dev_err(codec->dev, "write 0x%02x while offline\n", reg);
-		return -ENODEV;
-	}
-	dev_dbg(codec->dev, "write %x = %x\n", reg, val);
-	trace_snd_soc_reg_write(codec, reg, val);
-	return codec->write(codec, reg, val);
+	if (codec->write) {
+		if (unlikely(!snd_card_is_online_state(codec->card->snd_card))) {
+			dev_err(codec->dev, "write 0x%02x while offline\n", reg);
+			return -ENODEV;
+		}
+		dev_dbg(codec->dev, "write %x = %x\n", reg, val);
+		trace_snd_soc_reg_write(codec, reg, val);
+		return codec->write(codec, reg, val);
+        }
+	else
+		return -EIO;
 }
 EXPORT_SYMBOL_GPL(snd_soc_write);
 
-- 
GitLab