blob: a471b3cc4ef1c9c0bd8815793f2a3827da2c108e [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/"
16
17static pthread_t start_thread;
18static pthread_t stop_thread;
19static int rproc_state_fd;
20static int rproc_pipe[2];
21
22int rproc_init(void)
23{
24 struct dirent *device_de;
25 struct dirent *rproc_de;
26 int rproc_base_fd;
27 DIR *rproc_dir;
28 DIR *base_dir;
29 int device_fd;
30 int rproc_fd;
31 int base_fd;
32 int ret;
33
34 rproc_state_fd = -1;
35
36 base_fd = open(RPROC_BASE_PATH, O_RDONLY | O_DIRECTORY);
37 if (base_fd < 0)
38 return -1;
39
40 base_dir = fdopendir(base_fd);
41 if (!base_dir) {
42 fprintf(stderr, "failed to open mss driver path\n");
43 close(base_fd);
44 return -1;
45 }
46
47 while (rproc_state_fd < 0 && (device_de = readdir(base_dir)) != NULL) {
48 if (!strcmp(device_de->d_name, ".") ||
49 !strcmp(device_de->d_name, ".."))
50 continue;
51
52 device_fd = openat(base_fd, device_de->d_name, O_RDONLY | O_DIRECTORY);
53 if (device_fd < 0)
54 continue;
55
56 rproc_base_fd = openat(device_fd, "remoteproc", O_RDONLY | O_DIRECTORY);
57 if (rproc_base_fd < 0) {
58 close(device_fd);
59 continue;
60 }
61
62 rproc_dir = fdopendir(rproc_base_fd);
63 while (rproc_state_fd < 0 && (rproc_de = readdir(rproc_dir)) != NULL) {
64 if (!strcmp(rproc_de->d_name, ".") ||
65 !strcmp(rproc_de->d_name, ".."))
66 continue;
67
68 rproc_fd = openat(rproc_base_fd, rproc_de->d_name, O_RDONLY | O_DIRECTORY);
69 if (rproc_fd < 0)
70 continue;
71
72 rproc_state_fd = openat(rproc_fd, "state", O_WRONLY);
73 if (rproc_state_fd < 0) {
74 fprintf(stderr,
75 "unable to open remoteproc \"state\" control file of %s\n",
76 device_de->d_name);
77 }
78
79 close(rproc_fd);
80
81 }
82 closedir(rproc_dir);
83 close(rproc_base_fd);
84 close(device_fd);
85 }
86 closedir(base_dir);
87 close(base_fd);
88
89 if (rproc_state_fd < 0)
90 return -1;
91
92 ret = pipe(rproc_pipe);
93 if (ret < 0) {
94 close(rproc_state_fd);
95 return -1;
96 }
97
98 return rproc_pipe[0];
99}
100
101static void *do_rproc_start(void *unused)
102{
103 ssize_t ret;
104
105 ret = pwrite(rproc_state_fd, "start", 5, 0);
106 if (ret < 4)
107 fprintf(stderr, "failed to update start state\n");
108
109 return NULL;
110}
111
112int rproc_start()
113{
114 return pthread_create(&start_thread, NULL, do_rproc_start, NULL);
115}
116
117static void *do_rproc_stop(void *unused)
118{
119 ssize_t ret;
120
121 ret = pwrite(rproc_state_fd, "stop", 4, 0);
122 if (ret < 4)
123 fprintf(stderr, "failed to update stop state\n");
124
125 ret = write(rproc_pipe[1], "Y", 1);
126 if (ret != 1) {
127 fprintf(stderr, "failed to signal event loop about exit\n");
128 exit(0);
129 }
130
131 return NULL;
132}
133
134int rproc_stop(void)
135{
136 return pthread_create(&stop_thread, NULL, do_rproc_stop, NULL);
137}