1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/slab.h>
24#include <linux/dma-mapping.h>
25#include <linux/export.h>
26#include <linux/module.h>
27#include <video/mmp_disp.h>
28
29static struct mmp_overlay *path_get_overlay(struct mmp_path *path,
30 int overlay_id)
31{
32 if (path && overlay_id < path->overlay_num)
33 return &path->overlays[overlay_id];
34 return NULL;
35}
36
37static int path_check_status(struct mmp_path *path)
38{
39 int i;
40 for (i = 0; i < path->overlay_num; i++)
41 if (path->overlays[i].status)
42 return 1;
43
44 return 0;
45}
46
47
48
49
50
51
52
53
54static int path_get_modelist(struct mmp_path *path,
55 struct mmp_mode **modelist)
56{
57 BUG_ON(!path || !modelist);
58
59 if (path->panel && path->panel->get_modelist)
60 return path->panel->get_modelist(path->panel, modelist);
61
62 return 0;
63}
64
65
66
67
68
69
70
71
72static LIST_HEAD(panel_list);
73static LIST_HEAD(path_list);
74static DEFINE_MUTEX(disp_lock);
75
76
77
78
79
80
81
82
83
84
85void mmp_register_panel(struct mmp_panel *panel)
86{
87 struct mmp_path *path;
88
89 mutex_lock(&disp_lock);
90
91
92 list_add_tail(&panel->node, &panel_list);
93
94
95 list_for_each_entry(path, &path_list, node) {
96 if (!strcmp(panel->plat_path_name, path->name)) {
97 dev_info(panel->dev, "connect to path %s\n",
98 path->name);
99 path->panel = panel;
100 break;
101 }
102 }
103
104 mutex_unlock(&disp_lock);
105}
106EXPORT_SYMBOL_GPL(mmp_register_panel);
107
108
109
110
111
112
113
114
115void mmp_unregister_panel(struct mmp_panel *panel)
116{
117 struct mmp_path *path;
118
119 mutex_lock(&disp_lock);
120 list_del(&panel->node);
121
122 list_for_each_entry(path, &path_list, node) {
123 if (path->panel && path->panel == panel) {
124 dev_info(panel->dev, "disconnect from path %s\n",
125 path->name);
126 path->panel = NULL;
127 break;
128 }
129 }
130 mutex_unlock(&disp_lock);
131}
132EXPORT_SYMBOL_GPL(mmp_unregister_panel);
133
134
135
136
137
138
139
140
141struct mmp_path *mmp_get_path(const char *name)
142{
143 struct mmp_path *path;
144 int found = 0;
145
146 mutex_lock(&disp_lock);
147 list_for_each_entry(path, &path_list, node) {
148 if (!strcmp(name, path->name)) {
149 found = 1;
150 break;
151 }
152 }
153 mutex_unlock(&disp_lock);
154
155 return found ? path : NULL;
156}
157EXPORT_SYMBOL_GPL(mmp_get_path);
158
159
160
161
162
163
164
165
166struct mmp_path *mmp_register_path(struct mmp_path_info *info)
167{
168 int i;
169 size_t size;
170 struct mmp_path *path = NULL;
171 struct mmp_panel *panel;
172
173 size = sizeof(struct mmp_path)
174 + sizeof(struct mmp_overlay) * info->overlay_num;
175 path = kzalloc(size, GFP_KERNEL);
176 if (!path)
177 return NULL;
178
179
180 mutex_init(&path->access_ok);
181 path->dev = info->dev;
182 path->id = info->id;
183 path->name = info->name;
184 path->output_type = info->output_type;
185 path->overlay_num = info->overlay_num;
186 path->plat_data = info->plat_data;
187 path->ops.set_mode = info->set_mode;
188
189 mutex_lock(&disp_lock);
190
191 list_for_each_entry(panel, &panel_list, node) {
192 if (!strcmp(info->name, panel->plat_path_name)) {
193 dev_info(path->dev, "get panel %s\n", panel->name);
194 path->panel = panel;
195 break;
196 }
197 }
198
199 dev_info(path->dev, "register %s, overlay_num %d\n",
200 path->name, path->overlay_num);
201
202
203 if (!path->ops.check_status)
204 path->ops.check_status = path_check_status;
205 if (!path->ops.get_overlay)
206 path->ops.get_overlay = path_get_overlay;
207 if (!path->ops.get_modelist)
208 path->ops.get_modelist = path_get_modelist;
209
210
211 for (i = 0; i < path->overlay_num; i++) {
212 path->overlays[i].path = path;
213 path->overlays[i].id = i;
214 mutex_init(&path->overlays[i].access_ok);
215 path->overlays[i].ops = info->overlay_ops;
216 }
217
218
219 list_add_tail(&path->node, &path_list);
220
221 mutex_unlock(&disp_lock);
222 return path;
223}
224EXPORT_SYMBOL_GPL(mmp_register_path);
225
226
227
228
229
230
231
232void mmp_unregister_path(struct mmp_path *path)
233{
234 int i;
235
236 if (!path)
237 return;
238
239 mutex_lock(&disp_lock);
240
241 list_del(&path->node);
242
243
244 for (i = 0; i < path->overlay_num; i++)
245 mutex_destroy(&path->overlays[i].access_ok);
246
247 mutex_destroy(&path->access_ok);
248
249 kfree(path);
250 mutex_unlock(&disp_lock);
251}
252EXPORT_SYMBOL_GPL(mmp_unregister_path);
253
254MODULE_AUTHOR("Zhou Zhu <zzhu3@marvell.com>");
255MODULE_DESCRIPTION("Marvell MMP display framework");
256MODULE_LICENSE("GPL");
257