blob: 68dc3c9bc3fa46f115110b41a02d728774cc7bde [file] [log] [blame]
Amit Pundird477f822020-02-07 22:26:08 +05301#include <sys/syscall.h>
2#include <sys/types.h>
3#include <dirent.h>
4#include <errno.h>
5#include <fcntl.h>
6#include <stdint.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <pthread.h>
10#include <string.h>
11#include <unistd.h>
12
13#include "rmtfs.h"
14
15#define RPROC_BASE_PATH "/sys/bus/platform/drivers/qcom-q6v5-mss/"
Amit Pundir53c12872022-10-27 21:55:51 +053016#define RPROC_CLASS_PATH "/sys/class/remoteproc/"
Amit Pundird477f822020-02-07 22:26:08 +053017
18static pthread_t start_thread;
19static pthread_t stop_thread;
20static int rproc_state_fd;
21static int rproc_pipe[2];
22
Amit Pundir53c12872022-10-27 21:55:51 +053023static int rproc_init_by_modalias(void)
24{
25 struct dirent *rproc_de;
26 char modalias[256];
27 DIR *base_dir;
28 int modalias_fd;
29 int rproc_fd;
30 int state_fd = -1;
31 int base_fd;
32 int ret;
33
34 base_fd = open(RPROC_CLASS_PATH, O_RDONLY | O_DIRECTORY);
35 if (base_fd < 0)
36 return -1;
37
38 base_dir = fdopendir(base_fd);
39 if (!base_dir) {
40 fprintf(stderr, "failed to open remoteproc class path\n");
41 close(base_fd);
42 return -1;
43 }
44
45 while (state_fd < 0 && (rproc_de = readdir(base_dir)) != NULL) {
46 if (!strcmp(rproc_de->d_name, ".") ||
47 !strcmp(rproc_de->d_name, ".."))
48 continue;
49
50 rproc_fd = openat(base_fd, rproc_de->d_name, O_RDONLY | O_DIRECTORY);
51 if (rproc_fd < 0)
52 continue;
53
54 modalias_fd = openat(rproc_fd, "device/modalias", O_RDONLY);
55 if (modalias_fd < 0)
56 goto close_rproc_fd;
57
58 ret = read(modalias_fd, modalias, sizeof(modalias) - 1);
59 if (ret < 0)
60 goto close_modalias_fd;
61 modalias[ret] = '\0';
62
63 if (!strstr(modalias, "-mpss-pas") && !strstr(modalias, "-mss-pil"))
64 goto close_modalias_fd;
65
66 state_fd = openat(rproc_fd, "state", O_WRONLY);
67 if (state_fd < 0) {
68 fprintf(stderr,
69 "unable to open remoteproc \"state\" control file of %s\n",
70 rproc_de->d_name);
71 }
72
73close_modalias_fd:
74 close(modalias_fd);
75close_rproc_fd:
76 close(rproc_fd);
77 }
78 closedir(base_dir);
79 close(base_fd);
80
81 return state_fd;
82}
83
84static int rproc_init_by_mss_driver(void)
Amit Pundird477f822020-02-07 22:26:08 +053085{
86 struct dirent *device_de;
87 struct dirent *rproc_de;
88 int rproc_base_fd;
89 DIR *rproc_dir;
90 DIR *base_dir;
91 int device_fd;
92 int rproc_fd;
Amit Pundir53c12872022-10-27 21:55:51 +053093 int state_fd = -1;
Amit Pundird477f822020-02-07 22:26:08 +053094 int base_fd;
Amit Pundird477f822020-02-07 22:26:08 +053095
96 base_fd = open(RPROC_BASE_PATH, O_RDONLY | O_DIRECTORY);
97 if (base_fd < 0)
98 return -1;
99
100 base_dir = fdopendir(base_fd);
101 if (!base_dir) {
102 fprintf(stderr, "failed to open mss driver path\n");
103 close(base_fd);
104 return -1;
105 }
106
Amit Pundir53c12872022-10-27 21:55:51 +0530107 while (state_fd < 0 && (device_de = readdir(base_dir)) != NULL) {
Amit Pundird477f822020-02-07 22:26:08 +0530108 if (!strcmp(device_de->d_name, ".") ||
109 !strcmp(device_de->d_name, ".."))
110 continue;
111
112 device_fd = openat(base_fd, device_de->d_name, O_RDONLY | O_DIRECTORY);
113 if (device_fd < 0)
114 continue;
115
116 rproc_base_fd = openat(device_fd, "remoteproc", O_RDONLY | O_DIRECTORY);
117 if (rproc_base_fd < 0) {
118 close(device_fd);
119 continue;
120 }
121
122 rproc_dir = fdopendir(rproc_base_fd);
Amit Pundir53c12872022-10-27 21:55:51 +0530123 while (state_fd < 0 && (rproc_de = readdir(rproc_dir)) != NULL) {
Amit Pundird477f822020-02-07 22:26:08 +0530124 if (!strcmp(rproc_de->d_name, ".") ||
125 !strcmp(rproc_de->d_name, ".."))
126 continue;
127
128 rproc_fd = openat(rproc_base_fd, rproc_de->d_name, O_RDONLY | O_DIRECTORY);
129 if (rproc_fd < 0)
130 continue;
131
Amit Pundir53c12872022-10-27 21:55:51 +0530132 state_fd = openat(rproc_fd, "state", O_WRONLY);
133 if (state_fd < 0) {
Amit Pundird477f822020-02-07 22:26:08 +0530134 fprintf(stderr,
135 "unable to open remoteproc \"state\" control file of %s\n",
136 device_de->d_name);
137 }
138
139 close(rproc_fd);
140
141 }
142 closedir(rproc_dir);
143 close(rproc_base_fd);
144 close(device_fd);
145 }
146 closedir(base_dir);
147 close(base_fd);
148
Amit Pundir53c12872022-10-27 21:55:51 +0530149 return state_fd;
150}
151
152int rproc_init(void)
153{
154 int state_fd;
155 int ret;
156
157 state_fd = rproc_init_by_modalias();
158 if (state_fd < 0) {
159 state_fd = rproc_init_by_mss_driver();
160 if (state_fd < 0)
161 return -1;
162 }
Amit Pundird477f822020-02-07 22:26:08 +0530163
164 ret = pipe(rproc_pipe);
165 if (ret < 0) {
Amit Pundir53c12872022-10-27 21:55:51 +0530166 close(state_fd);
Amit Pundird477f822020-02-07 22:26:08 +0530167 return -1;
168 }
169
Amit Pundir53c12872022-10-27 21:55:51 +0530170 rproc_state_fd = state_fd;
171
Amit Pundird477f822020-02-07 22:26:08 +0530172 return rproc_pipe[0];
173}
174
John Stultz26656692020-02-26 23:41:07 +0000175static void *do_rproc_start(void *unused __unused)
Amit Pundird477f822020-02-07 22:26:08 +0530176{
177 ssize_t ret;
178
179 ret = pwrite(rproc_state_fd, "start", 5, 0);
Amit Pundir53c12872022-10-27 21:55:51 +0530180 if (ret < 4) {
181 fprintf(stderr, "failed to update start state: %s\n",
182 strerror(errno));
183 }
Amit Pundird477f822020-02-07 22:26:08 +0530184
185 return NULL;
186}
187
188int rproc_start()
189{
Amit Pundir53c12872022-10-27 21:55:51 +0530190 pthread_attr_t attr;
191
192 pthread_attr_init(&attr);
193 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
194
195 return pthread_create(&start_thread, &attr, do_rproc_start, NULL);
Amit Pundird477f822020-02-07 22:26:08 +0530196}
197
John Stultz26656692020-02-26 23:41:07 +0000198static void *do_rproc_stop(void *unused __unused)
Amit Pundird477f822020-02-07 22:26:08 +0530199{
200 ssize_t ret;
201
202 ret = pwrite(rproc_state_fd, "stop", 4, 0);
Amit Pundir53c12872022-10-27 21:55:51 +0530203 if (ret < 4) {
204 fprintf(stderr, "failed to update stop state: %s\n",
205 strerror(errno));
206 }
Amit Pundird477f822020-02-07 22:26:08 +0530207
208 ret = write(rproc_pipe[1], "Y", 1);
209 if (ret != 1) {
210 fprintf(stderr, "failed to signal event loop about exit\n");
211 exit(0);
212 }
213
214 return NULL;
215}
216
217int rproc_stop(void)
218{
Amit Pundir53c12872022-10-27 21:55:51 +0530219 pthread_attr_t attr;
220
221 pthread_attr_init(&attr);
222 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
223
224 return pthread_create(&stop_thread, &attr, do_rproc_stop, NULL);
Amit Pundird477f822020-02-07 22:26:08 +0530225}