aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-kernel/most/files/0006-dim2-fix-startup-sequence.patch
blob: 59c6ae6712ef646dc52bfc8337403104366c7a6a (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
From 63bcd9b421ae7927948bffec9566db47f40ea290 Mon Sep 17 00:00:00 2001
From: Andrey Shvetsov <andrey.shvetsov@k2l.de>
Date: Tue, 30 Jan 2018 17:34:09 +0100
Subject: [PATCH] staging: most: dim2: fix startup sequence

Platform specific initializations (pdata->init) must be done before DIM2
IP module startup (dim_startup).

Signed-off-by: Andrey Shvetsov <andrey.shvetsov@k2l.de>
---
 hdm-dim2/dim2_hdm.c | 90 +++++++++++++++++++++++++++++++++++++++---------------------------------------------------
 1 file changed, 39 insertions(+), 51 deletions(-)

diff --git a/hdm-dim2/dim2_hdm.c b/hdm-dim2/dim2_hdm.c
index 893b8e4..e4629a5 100644
--- a/hdm-dim2/dim2_hdm.c
+++ b/hdm-dim2/dim2_hdm.c
@@ -155,38 +155,6 @@ void dimcb_on_error(u8 error_id, const char *error_message)
 }

 /**
- * startup_dim - initialize the dim2 interface
- * @pdev: platform device
- */
-static int startup_dim(struct platform_device *pdev)
-{
-	struct dim2_hdm *dev = platform_get_drvdata(pdev);
-	struct dim2_platform_data *pdata = pdev->dev.platform_data;
-	u8 hal_ret;
-	int ret;
-
-	if (!pdata) {
-		pr_err("missing platform data\n");
-		return -EINVAL;
-	}
-
-	ret = pdata->init ? pdata->init(pdata, dev->io_base) : 0;
-	if (ret)
-		return ret;
-
-	pr_info("sync: num of frames per sub-buffer: %u\n", fcnt);
-	hal_ret = dim_startup(dev->io_base, pdata->clk_speed, fcnt);
-	if (hal_ret != DIM_NO_ERROR) {
-		pr_err("dim_startup failed: %d\n", hal_ret);
-		if (pdata && pdata->destroy)
-			pdata->destroy(pdata);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-/**
  * try_start_dim_transfer - try to transfer a buffer on a channel
  * @hdm_ch: channel specific data
  *
@@ -727,10 +695,12 @@ static void dma_free(struct mbo *mbo, u32 size)
  */
 static int dim2_probe(struct platform_device *pdev)
 {
+	struct dim2_platform_data *pdata = pdev->dev.platform_data;
	struct dim2_hdm *dev;
	struct resource *res;
	int ret, i;
	struct kobject *kobj;
+	u8 hal_ret;
	int irq;

	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
@@ -745,38 +715,59 @@ static int dim2_probe(struct platform_device *pdev)
	if (IS_ERR(dev->io_base))
		return PTR_ERR(dev->io_base);

+	if (!pdata) {
+		dev_err(&pdev->dev, "missing platform data\n");
+		return -EINVAL;
+	}
+
+	ret = pdata->init ? pdata->init(pdata, dev->io_base) : 0;
+	if (ret)
+		return ret;
+
+	dev_info(&pdev->dev, "sync: num of frames per sub-buffer: %u\n", fcnt);
+	hal_ret = dim_startup(dev->io_base, pdata->clk_speed, fcnt);
+	if (hal_ret != DIM_NO_ERROR) {
+		dev_err(&pdev->dev, "dim_startup failed: %d\n", hal_ret);
+		ret = -ENODEV;
+		goto err_bsp_destroy;
+	}
+
	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "failed to get ahb0_int irq: %d\n", irq);
-		return irq;
+		ret = irq;
+		goto err_shutdown_dim;
	}

	ret = devm_request_irq(&pdev->dev, irq, dim2_ahb_isr, 0,
			       "dim2_ahb0_int", dev);
	if (ret) {
		dev_err(&pdev->dev, "failed to request ahb0_int irq %d\n", irq);
-		return ret;
+		goto err_shutdown_dim;
	}

	irq = platform_get_irq(pdev, 1);
	if (irq < 0) {
		dev_err(&pdev->dev, "failed to get mlb_int irq: %d\n", irq);
-		return irq;
+		ret = irq;
+		goto err_shutdown_dim;
	}

	ret = devm_request_irq(&pdev->dev, irq, dim2_mlb_isr, 0,
			       "dim2_mlb_int", dev);
	if (ret) {
		dev_err(&pdev->dev, "failed to request mlb_int irq %d\n", irq);
-		return ret;
+		goto err_shutdown_dim;
	}

	init_waitqueue_head(&dev->netinfo_waitq);
	dev->deliver_netinfo = 0;
-	dev->netinfo_task = kthread_run(&deliver_netinfo_thread, (void *)dev,
+	dev->netinfo_task = kthread_run(&deliver_netinfo_thread, dev,
					"dim2_netinfo");
-	if (IS_ERR(dev->netinfo_task))
-		return PTR_ERR(dev->netinfo_task);
+	if (IS_ERR(dev->netinfo_task)) {
+		ret = PTR_ERR(dev->netinfo_task);
+		goto err_shutdown_dim;
+	}

	for (i = 0; i < DMA_CHANNELS; i++) {
		struct most_channel_capability *cap = dev->capabilities + i;
@@ -833,20 +824,17 @@ static int dim2_probe(struct platform_device *pdev)
	if (ret)
		goto err_unreg_iface;

-	ret = startup_dim(pdev);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to initialize DIM2\n");
-		goto err_destroy_bus;
-	}
-
	return 0;

-err_destroy_bus:
-	dim2_sysfs_destroy(&dev->bus);
 err_unreg_iface:
	most_deregister_interface(&dev->most_iface);
 err_stop_thread:
	kthread_stop(dev->netinfo_task);
+err_shutdown_dim:
+	dim_shutdown();
+err_bsp_destroy:
+	if (pdata && pdata->destroy)
+		pdata->destroy(pdata);

	return ret;
 }
@@ -863,6 +851,10 @@ static int dim2_remove(struct platform_device *pdev)
	struct dim2_platform_data *pdata = pdev->dev.platform_data;
	unsigned long flags;

+	dim2_sysfs_destroy(&dev->bus);
+	most_deregister_interface(&dev->most_iface);
+	kthread_stop(dev->netinfo_task);
+
	spin_lock_irqsave(&dim_lock, flags);
	dim_shutdown();
	spin_unlock_irqrestore(&dim_lock, flags);
@@ -870,10 +862,6 @@ static int dim2_remove(struct platform_device *pdev)
	if (pdata && pdata->destroy)
		pdata->destroy(pdata);

-	dim2_sysfs_destroy(&dev->bus);
-	most_deregister_interface(&dev->most_iface);
-	kthread_stop(dev->netinfo_task);
-
	/*
	 * break link to local platform_device_id struct
	 * to prevent crash by unload platform device module
--
libgit2 0.26.0