aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/808-i2c-0016-LF-162-i2c-imx-Defer-probing-if-EDMA-not-available.patch
blob: 815cb0efe6cf19092ec70e8d0927a293ad1854cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
From 9de3b340d84b75f93081f871b640a065cba4ded0 Mon Sep 17 00:00:00 2001
From: Peng Ma <peng.ma@nxp.com>
Date: Tue, 26 Nov 2019 16:02:00 +0800
Subject: [PATCH] LF-162: i2c: imx: Defer probing if EDMA not available

EDMA may be not available or defered due to dependencies on
other modules, If these scenarios is encountered, we should
defer probing.

Signed-off-by: Peng Ma <peng.ma@nxp.com>
---
 drivers/i2c/busses/i2c-imx.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -369,8 +369,8 @@ static void i2c_imx_reset_regs(struct im
 }
 
 /* Functions for DMA support */
-static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
-						dma_addr_t phy_addr)
+static int i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
+			       dma_addr_t phy_addr)
 {
 	struct imx_i2c_dma *dma;
 	struct dma_slave_config dma_sconfig;
@@ -379,7 +379,7 @@ static void i2c_imx_dma_request(struct i
 
 	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
 	if (!dma)
-		return;
+		return -ENOMEM;
 
 	dma->chan_tx = dma_request_chan(dev, "tx");
 	if (IS_ERR(dma->chan_tx)) {
@@ -424,7 +424,7 @@ static void i2c_imx_dma_request(struct i
 	dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n",
 		dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx));
 
-	return;
+	return 0;
 
 fail_rx:
 	dma_release_channel(dma->chan_rx);
@@ -432,6 +432,8 @@ fail_tx:
 	dma_release_channel(dma->chan_tx);
 fail_al:
 	devm_kfree(dev, dma);
+
+	return ret;
 }
 
 static void i2c_imx_dma_callback(void *arg)
@@ -1633,10 +1635,14 @@ static int i2c_imx_probe(struct platform
 	dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
 
 	/* Init DMA config if supported */
-	i2c_imx_dma_request(i2c_imx, phy_addr);
+	ret = i2c_imx_dma_request(i2c_imx, phy_addr);
+	if (ret == -EPROBE_DEFER)
+		goto i2c_adapter_remove;
 
 	return 0;   /* Return OK */
 
+i2c_adapter_remove:
+	i2c_del_adapter(&i2c_imx->adapter);
 clk_notifier_unregister:
 	clk_notifier_unregister(i2c_imx->clk, &i2c_imx->clk_change_nb);
 	free_irq(irq, i2c_imx);