qcom: Add userspace tools to talk to dsp and modem
cherry-picked from upstream device/linaro/dragonboard project.
Add Qcom userspace tools and their respective sepolicy rules.
Userspace tools are downloaded from following github:
To trigger loading of wlan firmware on SDM845
git clone https://github.com/andersson/pd-mapper
Userspace reference for net/qrtr in the Linux kernel
git clone https://github.com/andersson/qrtr
Qualcomm Remote Filesystem Service Implementation
git clone https://github.com/andersson/rmtfs
Trivial File Transfer Protocol server over AF_QIPCRTR
git clone https://github.com/andersson/tqftpserv
Change-Id: Ic466af6fef010a9b71c90e38205f49a876b001e2
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Amit Pundir <pundiramit@gmail.com>
diff --git a/qcom/rmtfs/rproc.c b/qcom/rmtfs/rproc.c
new file mode 100644
index 0000000..a471b3c
--- /dev/null
+++ b/qcom/rmtfs/rproc.c
@@ -0,0 +1,137 @@
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "rmtfs.h"
+
+#define RPROC_BASE_PATH "/sys/bus/platform/drivers/qcom-q6v5-mss/"
+
+static pthread_t start_thread;
+static pthread_t stop_thread;
+static int rproc_state_fd;
+static int rproc_pipe[2];
+
+int rproc_init(void)
+{
+ struct dirent *device_de;
+ struct dirent *rproc_de;
+ int rproc_base_fd;
+ DIR *rproc_dir;
+ DIR *base_dir;
+ int device_fd;
+ int rproc_fd;
+ int base_fd;
+ int ret;
+
+ rproc_state_fd = -1;
+
+ base_fd = open(RPROC_BASE_PATH, O_RDONLY | O_DIRECTORY);
+ if (base_fd < 0)
+ return -1;
+
+ base_dir = fdopendir(base_fd);
+ if (!base_dir) {
+ fprintf(stderr, "failed to open mss driver path\n");
+ close(base_fd);
+ return -1;
+ }
+
+ while (rproc_state_fd < 0 && (device_de = readdir(base_dir)) != NULL) {
+ if (!strcmp(device_de->d_name, ".") ||
+ !strcmp(device_de->d_name, ".."))
+ continue;
+
+ device_fd = openat(base_fd, device_de->d_name, O_RDONLY | O_DIRECTORY);
+ if (device_fd < 0)
+ continue;
+
+ rproc_base_fd = openat(device_fd, "remoteproc", O_RDONLY | O_DIRECTORY);
+ if (rproc_base_fd < 0) {
+ close(device_fd);
+ continue;
+ }
+
+ rproc_dir = fdopendir(rproc_base_fd);
+ while (rproc_state_fd < 0 && (rproc_de = readdir(rproc_dir)) != NULL) {
+ if (!strcmp(rproc_de->d_name, ".") ||
+ !strcmp(rproc_de->d_name, ".."))
+ continue;
+
+ rproc_fd = openat(rproc_base_fd, rproc_de->d_name, O_RDONLY | O_DIRECTORY);
+ if (rproc_fd < 0)
+ continue;
+
+ rproc_state_fd = openat(rproc_fd, "state", O_WRONLY);
+ if (rproc_state_fd < 0) {
+ fprintf(stderr,
+ "unable to open remoteproc \"state\" control file of %s\n",
+ device_de->d_name);
+ }
+
+ close(rproc_fd);
+
+ }
+ closedir(rproc_dir);
+ close(rproc_base_fd);
+ close(device_fd);
+ }
+ closedir(base_dir);
+ close(base_fd);
+
+ if (rproc_state_fd < 0)
+ return -1;
+
+ ret = pipe(rproc_pipe);
+ if (ret < 0) {
+ close(rproc_state_fd);
+ return -1;
+ }
+
+ return rproc_pipe[0];
+}
+
+static void *do_rproc_start(void *unused)
+{
+ ssize_t ret;
+
+ ret = pwrite(rproc_state_fd, "start", 5, 0);
+ if (ret < 4)
+ fprintf(stderr, "failed to update start state\n");
+
+ return NULL;
+}
+
+int rproc_start()
+{
+ return pthread_create(&start_thread, NULL, do_rproc_start, NULL);
+}
+
+static void *do_rproc_stop(void *unused)
+{
+ ssize_t ret;
+
+ ret = pwrite(rproc_state_fd, "stop", 4, 0);
+ if (ret < 4)
+ fprintf(stderr, "failed to update stop state\n");
+
+ ret = write(rproc_pipe[1], "Y", 1);
+ if (ret != 1) {
+ fprintf(stderr, "failed to signal event loop about exit\n");
+ exit(0);
+ }
+
+ return NULL;
+}
+
+int rproc_stop(void)
+{
+ return pthread_create(&stop_thread, NULL, do_rproc_stop, NULL);
+}