From 3449744146b0a1b68810b81bd51fe5ef285e2388 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Sat, 21 Nov 2020 00:02:39 -0600 Subject: [PATCH] rproc: Support -s for PAS based remoteproc as well The old mechanism searched for remoteproc instances from the qcom_q6v5_mss driver, but in modern platforms the MSA based remoteproc model has been replaced by the PAS based one. As such we use the common qcom_q6v5_pas driver - as with other subsystems. Use the modalias to find remoteproc drivers with the mpss-pas or mss-pil compatible to find these, and fall back to the old heuristics if this fails. Signed-off-by: Bjorn Andersson --- rproc.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 11 deletions(-) diff --git a/rproc.c b/rproc.c index a471b3c..d104490 100644 --- a/rproc.c +++ b/rproc.c @@ -13,13 +13,74 @@ #include "rmtfs.h" #define RPROC_BASE_PATH "/sys/bus/platform/drivers/qcom-q6v5-mss/" +#define RPROC_CLASS_PATH "/sys/class/remoteproc/" static pthread_t start_thread; static pthread_t stop_thread; static int rproc_state_fd; static int rproc_pipe[2]; -int rproc_init(void) +static int rproc_init_by_modalias(void) +{ + struct dirent *rproc_de; + char modalias[256]; + DIR *base_dir; + int modalias_fd; + int rproc_fd; + int state_fd = -1; + int base_fd; + int ret; + + base_fd = open(RPROC_CLASS_PATH, O_RDONLY | O_DIRECTORY); + if (base_fd < 0) + return -1; + + base_dir = fdopendir(base_fd); + if (!base_dir) { + fprintf(stderr, "failed to open remoteproc class path\n"); + close(base_fd); + return -1; + } + + while (state_fd < 0 && (rproc_de = readdir(base_dir)) != NULL) { + if (!strcmp(rproc_de->d_name, ".") || + !strcmp(rproc_de->d_name, "..")) + continue; + + rproc_fd = openat(base_fd, rproc_de->d_name, O_RDONLY | O_DIRECTORY); + if (rproc_fd < 0) + continue; + + modalias_fd = openat(rproc_fd, "device/modalias", O_RDONLY); + if (modalias_fd < 0) + goto close_rproc_fd; + + ret = read(modalias_fd, modalias, sizeof(modalias)); + if (ret < 0) + goto close_modalias_fd; + + if (!strstr(modalias, "-mpss-pas") && !strstr(modalias, "-mss-pil")) + goto close_modalias_fd; + + state_fd = openat(rproc_fd, "state", O_WRONLY); + if (state_fd < 0) { + fprintf(stderr, + "unable to open remoteproc \"state\" control file of %s\n", + rproc_de->d_name); + } + +close_modalias_fd: + close(modalias_fd); +close_rproc_fd: + close(rproc_fd); + } + closedir(base_dir); + close(base_fd); + + return state_fd; +} + +static int rproc_init_by_mss_driver(void) { struct dirent *device_de; struct dirent *rproc_de; @@ -28,10 +89,8 @@ int rproc_init(void) DIR *base_dir; int device_fd; int rproc_fd; + int state_fd = -1; int base_fd; - int ret; - - rproc_state_fd = -1; base_fd = open(RPROC_BASE_PATH, O_RDONLY | O_DIRECTORY); if (base_fd < 0) @@ -44,7 +103,7 @@ int rproc_init(void) return -1; } - while (rproc_state_fd < 0 && (device_de = readdir(base_dir)) != NULL) { + while (state_fd < 0 && (device_de = readdir(base_dir)) != NULL) { if (!strcmp(device_de->d_name, ".") || !strcmp(device_de->d_name, "..")) continue; @@ -60,7 +119,7 @@ int rproc_init(void) } rproc_dir = fdopendir(rproc_base_fd); - while (rproc_state_fd < 0 && (rproc_de = readdir(rproc_dir)) != NULL) { + while (state_fd < 0 && (rproc_de = readdir(rproc_dir)) != NULL) { if (!strcmp(rproc_de->d_name, ".") || !strcmp(rproc_de->d_name, "..")) continue; @@ -69,8 +128,8 @@ int rproc_init(void) if (rproc_fd < 0) continue; - rproc_state_fd = openat(rproc_fd, "state", O_WRONLY); - if (rproc_state_fd < 0) { + state_fd = openat(rproc_fd, "state", O_WRONLY); + if (state_fd < 0) { fprintf(stderr, "unable to open remoteproc \"state\" control file of %s\n", device_de->d_name); @@ -86,15 +145,29 @@ int rproc_init(void) closedir(base_dir); close(base_fd); - if (rproc_state_fd < 0) - return -1; + return state_fd; +} + +int rproc_init(void) +{ + int state_fd; + int ret; + + state_fd = rproc_init_by_modalias(); + if (state_fd < 0) { + state_fd = rproc_init_by_mss_driver(); + if (state_fd < 0) + return -1; + } ret = pipe(rproc_pipe); if (ret < 0) { - close(rproc_state_fd); + close(state_fd); return -1; } + rproc_state_fd = state_fd; + return rproc_pipe[0]; }