Browse Source

Merge 7570178ce355bdcd3f1e0785a6b5b5e64fa6e1ce on remote branch

Change-Id: I392ea6a83e17531c8b35d3f10e5e8131b089a23a
Linux Build Service Account 2 năm trước cách đây
mục cha
commit
f1d0d8ba67

+ 27 - 0
BUILD.bazel

@@ -0,0 +1,27 @@
+package(
+    default_visibility = [
+        "//visibility:public",
+    ],
+)
+
+load("//build/kernel/kleaf:kernel.bzl", "ddk_headers")
+
+driver_header_globs = [
+    "include/uapi/synx/**/*.h",
+    "include/uapi/synx/media/**/*.h",
+    "msm/synx/**/*.h",
+]
+
+ddk_headers(
+    name = "synx_headers",
+    hdrs = glob(driver_header_globs),
+    includes = [
+        "include/uapi/synx",
+        "include/uapi/synx/media",
+        "msm/synx",
+    ],
+)
+
+load(":pineapple.bzl", "define_pineapple")
+
+define_pineapple()

+ 18 - 0
dt-bindings/ipclite-signals.h

@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __DT_BINDINGS_IPCLITE_SIGNALS_H
+#define __DT_BINDINGS_IPCLITE_SIGNALS_H
+
+/* Signal IDs for COMPUTE_L0 protocol */
+#define IPCC_COMPUTE_L0_SIGNAL_IPCLITE_MSG			0
+#define IPCC_COMPUTE_L0_SIGNAL_IPCLITE_MEM_INIT		1
+#define IPCC_COMPUTE_L0_SIGNAL_IPCLITE_VERSION		2
+#define IPCC_COMPUTE_L0_SIGNAL_IPCLITE_TEST			3
+#define IPCC_COMPUTE_L0_SIGNAL_IPCLITE_SSR			4
+#define IPCC_COMPUTE_L0_SIGNAL_IPCLITE_DEBUG		5
+
+#endif

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 520 - 105
msm/synx/ipclite.c


+ 94 - 4
msm/synx/ipclite.h

@@ -14,7 +14,7 @@
 #define ACTIVE_CHANNEL			0x1
 
 #define IPCMEM_TOC_SIZE			(4*1024)
-#define MAX_CHANNEL_SIGNALS		5
+#define MAX_CHANNEL_SIGNALS		6
 
 #define MAX_PARTITION_COUNT		11	/*11 partitions other than global partition*/
 
@@ -23,6 +23,7 @@
 #define IPCLITE_VERSION_SIGNAL  2
 #define IPCLITE_TEST_SIGNAL		3
 #define IPCLITE_SSR_SIGNAL		4
+#define IPCLITE_DEBUG_SIGNAL	5
 
 /** Flag definitions for the entries */
 #define IPCMEM_TOC_ENTRY_FLAGS_ENABLE_READ_PROTECTION   (0x01)
@@ -45,8 +46,97 @@
 
 #define CONFIGURED_CORE		1
 
+#define IPCLITE_DEBUG_SIZE			(64 * 1024)
+#define IPCLITE_DEBUG_INFO_SIZE		256
+#define IPCLITE_CORE_DBG_LABEL		"APSS:"
+#define IPCLITE_LOG_MSG_SIZE		100
+#define IPCLITE_LOG_BUF_SIZE		512
+#define IPCLITE_DBG_LABEL_SIZE		5
+#define IPCLITE_SIGNAL_LABEL_SIZE	10
+#define PREV_INDEX					2
+
+#define IPCLITE_OS_LOG(__level, __fmt, arg...) \
+	do { \
+		if (ipclite_debug_level & __level) { \
+			if (ipclite_debug_control & IPCLITE_DMESG_LOG) { \
+				pr_info(IPCLITE_CORE_DBG_LABEL "%s:"__fmt, \
+							ipclite_dbg_label[__level], ## arg); \
+			} \
+			if (ipclite_debug_control & IPCLITE_INMEM_LOG) { \
+				IPCLITE_OS_INMEM_LOG(IPCLITE_CORE_DBG_LABEL "%s:"__fmt, \
+							ipclite_dbg_label[__level], ## arg); \
+			} \
+		} \
+	} while (0)
+
 /*IPCMEM Structure Definitions*/
 
+enum ipclite_debug_level {
+	IPCLITE_ERR  = 0x0001,
+	IPCLITE_WARN = 0x0002,
+	IPCLITE_INFO = 0x0004,
+	IPCLITE_DBG  = 0x0008,
+};
+
+enum ipclite_debug_control {
+	IPCLITE_DMESG_LOG = 0x0001,
+	IPCLITE_DBG_STRUCT = 0x0002,
+	IPCLITE_INMEM_LOG = 0x0004,
+};
+
+enum ipclite_debug_dump {
+	IPCLITE_DUMP_DBG_STRUCT = 0x0001,
+	IPCLITE_DUMP_INMEM_LOG = 0x0002,
+	IPCLITE_DUMP_SSR = 0x0004,
+};
+
+static const char ipclite_dbg_label[][IPCLITE_DBG_LABEL_SIZE] = {
+	[IPCLITE_ERR] = "err",
+	[IPCLITE_WARN] = "warn",
+	[IPCLITE_INFO] = "info",
+	[IPCLITE_DBG] = "dbg"
+};
+
+struct ipclite_debug_info_host {
+	uint32_t numsig_sent; //no. of signals sent from the core
+	uint32_t numsig_recv; //no. of signals received on the core
+	uint32_t tx_wr_index; //write index of tx queue
+	uint32_t tx_rd_index; //read index of tx queue
+	uint32_t rx_wr_index; //write index of rx queue
+	uint32_t rx_rd_index; //read index of rx queue
+	uint32_t num_intr; //no. of interrupts received on the core
+	uint32_t prev_tx_wr_index[PREV_INDEX]; //previous write index of tx queue
+	uint32_t prev_tx_rd_index[PREV_INDEX]; //previous read index of tx queue
+	uint32_t prev_rx_wr_index[PREV_INDEX]; //previous write index of rx queue
+	uint32_t prev_rx_rd_index[PREV_INDEX]; //previous read index of rx queue
+};
+
+struct ipclite_debug_info_overall {
+	uint32_t total_numsig_sent; //total no. of signals sent
+	uint32_t total_numsig_recv; //total no. of signals received
+	uint32_t last_sent_host_id; //last signal sent to host
+	uint32_t last_recv_host_id; //last signal received from host
+	uint32_t last_sigid_sent; //last sent signal id
+	uint32_t last_sigid_recv; //last received signal id
+};
+
+struct ipclite_debug_info {
+	uint32_t debug_version;
+	uint32_t debug_level;
+	uint32_t debug_control;
+	uint32_t debug_dump;
+	uint32_t debug_log_index;
+};
+
+struct ipclite_debug_inmem_buf {
+	char IPCLITELog[IPCLITE_LOG_BUF_SIZE][IPCLITE_LOG_MSG_SIZE];
+};
+
+struct ipclite_debug_struct {
+	struct ipclite_debug_info_overall dbg_info_overall;
+	struct ipclite_debug_info_host dbg_info_host[IPCMEM_NUM_HOSTS];
+};
+
 struct ipclite_features {
 	uint32_t global_atomic_support;
 	uint32_t version_finalised;
@@ -130,13 +220,13 @@ struct ipclite_fifo {
 	size_t (*avail)(struct ipclite_fifo *fifo);
 
 	void (*peak)(struct ipclite_fifo *fifo,
-			       void *data, size_t count);
+					void *data, size_t count);
 
 	void (*advance)(struct ipclite_fifo *fifo,
-				  size_t count);
+					size_t count, uint32_t core_id);
 
 	void (*write)(struct ipclite_fifo *fifo,
-				const void *data, size_t dlen);
+		const void *data, size_t dlen, uint32_t core_id, uint32_t signal_id);
 
 	void (*reset)(struct ipclite_fifo *fifo);
 };

+ 3 - 1
msm/synx/ipclite_client.h

@@ -30,7 +30,9 @@ enum ipcmem_host_type {
 /**
  * IPCLite return codes
  */
-#define IPCLITE_EINCHAN				9 /**< Inactive Channel */
+#define IPCLITE_SUCCESS		0 /*< Success > */
+#define IPCLITE_FAILURE		1 /*< Failure > */
+#define IPCLITE_EINCHAN		9 /*< Inactive Channel */
 
 struct global_region_info {
 	void *virt_base;

+ 22 - 2
msm/synx/synx.c

@@ -519,6 +519,13 @@ void synx_signal_handler(struct work_struct *cb_dispatch)
 			dprintk(SYNX_ERR,
 				"global status update of %u failed=%d\n",
 				h_synx, rc);
+		/*
+		 * We are decrementing the reference here assuming this code will be
+		 * executed after handle is released. But in case if clients signal
+		 * dma fence in middle of execution sequence, then we will put
+		 * one reference thus deleting the global idx. As of now clients cannot
+		 * signal dma fence.
+		 */
 		synx_global_put_ref(idx);
 	}
 
@@ -573,6 +580,7 @@ fail:
 void synx_fence_callback(struct dma_fence *fence,
 	struct dma_fence_cb *cb)
 {
+	s32 status;
 	struct synx_signal_cb *signal_cb =
 		container_of(cb, struct synx_signal_cb, fence_cb);
 
@@ -581,7 +589,19 @@ void synx_fence_callback(struct dma_fence *fence,
 		fence, signal_cb->handle);
 
 	/* other signal_cb members would be set during cb registration */
-	signal_cb->status = dma_fence_get_status_locked(fence);
+	status = dma_fence_get_status_locked(fence);
+
+	/*
+	 * dma_fence_get_status_locked API returns 1 if signaled,
+	 * 0 if ACTIVE,
+	 * and negative error code in case of any failure
+	 */
+	if (status == 1)
+		status = SYNX_STATE_SIGNALED_SUCCESS;
+	else if (status < 0)
+		status = SYNX_STATE_SIGNALED_EXTERNAL;
+
+	signal_cb->status = status;
 
 	INIT_WORK(&signal_cb->cb_dispatch, synx_signal_handler);
 	queue_work(synx_dev->wq_cb, &signal_cb->cb_dispatch);
@@ -2427,7 +2447,7 @@ int synx_ipc_callback(u32 client_id,
 	if (IS_ERR_OR_NULL(signal_cb))
 		return -SYNX_NOMEM;
 
-	dprintk(SYNX_INFO,
+	dprintk(SYNX_DBG,
 		"signal notification for %u received with status %u\n",
 		handle, status);
 

+ 11 - 1
msm/synx/synx_api.h

@@ -12,6 +12,14 @@
 
 #include "synx_err.h"
 
+#define SYNX_NO_TIMEOUT        ((u64)-1)
+
+/**
+ * SYNX_INVALID_HANDLE      : client can assign the synx handle variable with this value
+ *                            when it doesn't hold a valid synx handle
+ */
+#define SYNX_INVALID_HANDLE 0
+
 /**
  * enum synx_create_flags - Flags passed during synx_create call
  *
@@ -87,7 +95,7 @@ typedef void (*synx_callback)(s32 sync_obj, int status, void *data);
  * synx_user_callback - Callback function registered by clients
  *
  * User callback registered for non-blocking wait. Dispatched when
- * synx object is signaled.
+ * synx object is signaled or timeout has expired.
  */
 typedef void (*synx_user_callback_t)(u32 h_synx, int status, void *data);
 
@@ -330,12 +338,14 @@ struct synx_import_params {
  * @cb_func        : Pointer to callback func to be invoked
  * @userdata       : Opaque pointer passed back with callback
  * @cancel_cb_func : Pointer to callback to ack cancellation (optional)
+ * @timeout_ms     : Timeout in ms. SYNX_NO_TIMEOUT if no timeout.
  */
 struct synx_callback_params {
 	u32 h_synx;
 	synx_user_callback_t cb_func;
 	void *userdata;
 	synx_user_callback_t cancel_cb_func;
+	u64 timeout_ms;
 };
 
 /* Kernel APIs */

+ 2 - 2
msm/synx/synx_debugfs.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/io.h>
@@ -23,7 +23,7 @@ int synx_columns = NAME_COLUMN | ID_COLUMN |
 EXPORT_SYMBOL(synx_columns);
 
 int synx_debug = SYNX_ERR | SYNX_WARN |
-	SYNX_INFO | SYNX_DBG;
+	SYNX_INFO;
 EXPORT_SYMBOL(synx_debug);
 
 void populate_bound_rows(

+ 53 - 2
msm/synx/synx_global.c

@@ -208,6 +208,24 @@ int synx_global_init_coredata(u32 h_synx)
 	if (rc)
 		return rc;
 	synx_g_obj = &synx_gmem.table[idx];
+	if (synx_g_obj->status != 0 || synx_g_obj->refcount != 0 ||
+		synx_g_obj->subscribers != 0 || synx_g_obj->handle != 0 ||
+		synx_g_obj->parents[0] != 0) {
+		dprintk(SYNX_ERR,
+				"entry not cleared for idx %u,\n"
+				"synx_g_obj->status %d,\n"
+				"synx_g_obj->refcount %d,\n"
+				"synx_g_obj->subscribers %d,\n"
+				"synx_g_obj->handle %u,\n"
+				"synx_g_obj->parents[0] %d\n",
+				idx, synx_g_obj->status,
+				synx_g_obj->refcount,
+				synx_g_obj->subscribers,
+				synx_g_obj->handle,
+				synx_g_obj->parents[0]);
+		synx_gmem_unlock(idx, &flags);
+		return -SYNX_INVALID;
+	}
 	memset(synx_g_obj, 0, sizeof(*synx_g_obj));
 	/* set status to active */
 	synx_g_obj->status = SYNX_STATE_ACTIVE;
@@ -332,6 +350,28 @@ int synx_global_set_subscribed_core(u32 idx, enum synx_core_id id)
 	return SYNX_SUCCESS;
 }
 
+int synx_global_clear_subscribed_core(u32 idx, enum synx_core_id id)
+{
+	int rc;
+	unsigned long flags;
+	struct synx_global_coredata *synx_g_obj;
+
+	if (!synx_gmem.table)
+		return -SYNX_NOMEM;
+
+	if (id >= SYNX_CORE_MAX || !synx_is_valid_idx(idx))
+		return -SYNX_INVALID;
+
+	rc = synx_gmem_lock(idx, &flags);
+	if (rc)
+		return rc;
+	synx_g_obj = &synx_gmem.table[idx];
+	synx_g_obj->subscribers &= ~(1UL << id);
+	synx_gmem_unlock(idx, &flags);
+
+	return SYNX_SUCCESS;
+}
+
 u32 synx_global_get_parents_num(u32 idx)
 {
 	int rc;
@@ -528,7 +568,18 @@ static int synx_global_update_status_core(u32 idx,
 	/* notify waiting clients on signal */
 	if (data) {
 		/* notify wait client */
-		for (i = 1; i < SYNX_CORE_MAX; i++) {
+
+	/* In case of SSR, someone might be waiting on same core
+	 * However, in other cases, synx_signal API will take care
+	 * of signaling handles on same core and thus we don't need
+	 * to send interrupt
+	 */
+		if (status == SYNX_STATE_SIGNALED_SSR)
+			i = 0;
+		else
+			i = 1;
+
+		for (; i < SYNX_CORE_MAX ; i++) {
 			if (!wait_cores[i])
 				continue;
 			dprintk(SYNX_DBG,
@@ -735,7 +786,7 @@ int synx_global_recover(enum synx_core_id core_id)
 	const u32 size = SYNX_GLOBAL_MAX_OBJS;
 	unsigned long flags;
 	struct synx_global_coredata *synx_g_obj;
-	
+
 	bool update;
 	int *clear_idx = NULL;
 	if (!synx_gmem.table)

+ 10 - 0
msm/synx/synx_global.h

@@ -179,6 +179,16 @@ int synx_global_get_subscribed_cores(u32 idx, bool *cores);
  */
 int synx_global_set_subscribed_core(u32 idx, enum synx_core_id id);
 
+/**
+ * synx_global_clear_subscribed_core - Clear core as a subscriber core on global entry
+ *
+ * @param idx : Global entry index
+ * @param id  : Core to be added as subscriber
+ *
+ * @return SYNX_SUCCESS on success. Negative error on failure.
+ */
+int synx_global_clear_subscribed_core(u32 idx, enum synx_core_id id);
+
 /**
  * synx_global_get_status - Get status of the global entry
  *

+ 32 - 3
msm/synx/synx_util.c

@@ -223,11 +223,17 @@ int synx_util_init_group_coredata(struct synx_coredata *synx_obj,
 
 static void synx_util_destroy_coredata(struct kref *kref)
 {
+	int rc;
 	struct synx_coredata *synx_obj =
 		container_of(kref, struct synx_coredata, refcount);
 
-	if (synx_util_is_global_object(synx_obj))
+	if (synx_util_is_global_object(synx_obj)) {
+		rc = synx_global_clear_subscribed_core(synx_obj->global_idx, SYNX_CORE_APSS);
+		if (rc)
+			dprintk(SYNX_ERR, "Failed to clear subscribers");
+
 		synx_global_put_ref(synx_obj->global_idx);
+	}
 	synx_util_object_destroy(synx_obj);
 }
 
@@ -247,6 +253,7 @@ void synx_util_object_destroy(struct synx_coredata *synx_obj)
 	u32 i;
 	s32 sync_id;
 	u32 type;
+	unsigned long flags;
 	struct synx_cb_data *synx_cb, *synx_cb_temp;
 	struct synx_bind_desc *bind_desc;
 	struct bind_operations *bind_ops;
@@ -297,6 +304,29 @@ void synx_util_object_destroy(struct synx_coredata *synx_obj)
 
 	mutex_destroy(&synx_obj->obj_lock);
 	synx_util_release_fence_entry((u64)synx_obj->fence);
+
+	/* dma fence framework expects handles are signaled before release,
+	 * so signal if active handle and has last refcount. Synx handles
+	 * on other cores are still active to carry out usual callflow.
+	 */
+	if (!IS_ERR_OR_NULL(synx_obj->fence)) {
+		spin_lock_irqsave(synx_obj->fence->lock, flags);
+		if (kref_read(&synx_obj->fence->refcount) == 1 &&
+				(synx_util_get_object_status_locked(synx_obj) ==
+				SYNX_STATE_ACTIVE)) {
+			// set fence error to cancel
+			dma_fence_set_error(synx_obj->fence,
+				-SYNX_STATE_SIGNALED_CANCEL);
+
+			rc = dma_fence_signal_locked(synx_obj->fence);
+			if (rc)
+				dprintk(SYNX_ERR,
+					"signaling fence %pK failed=%d\n",
+					synx_obj->fence, rc);
+		}
+		spin_unlock_irqrestore(synx_obj->fence->lock, flags);
+	}
+
 	dma_fence_put(synx_obj->fence);
 	kfree(synx_obj);
 	dprintk(SYNX_MEM, "released synx object %pK\n", synx_obj);
@@ -873,7 +903,6 @@ static void synx_util_cleanup_fence(
 			if (synx_util_get_object_status_locked(synx_obj) ==
 				SYNX_STATE_ACTIVE) {
 				signal_cb->synx_obj = NULL;
-				signal_cb->handle = synx_obj->global_idx;
 				synx_obj->signal_cb =  NULL;
 				/*
 				 * release reference held by signal cb and
@@ -1162,7 +1191,7 @@ void synx_util_cb_dispatch(struct work_struct *cb_dispatch)
 				client->id);
 	}
 
-	dprintk(SYNX_INFO,
+	dprintk(SYNX_DBG,
 		"callback dispatched for handle %u, status %u, data %pK\n",
 		payload.h_synx, payload.status, payload.data);
 

+ 15 - 0
pineapple.bzl

@@ -0,0 +1,15 @@
+load(":synx_modules.bzl", "synx_modules")
+load(":synx_module_build.bzl", "define_consolidate_gki_modules")
+
+def define_pineapple():
+    define_consolidate_gki_modules(
+        target = "pineapple",
+        registry = synx_modules,
+        modules = [
+            "synx",
+            "ipclite",
+        ],
+        config_options = [
+            "TARGET_SYNX_ENABLE",
+        ],
+    )

+ 128 - 0
synx_module_build.bzl

@@ -0,0 +1,128 @@
+load(
+    "//build/kernel/kleaf:kernel.bzl",
+    "ddk_module",
+    "ddk_submodule",
+    "kernel_module",
+    "kernel_modules_install",
+)
+load("//build/bazel_common_rules/dist:dist.bzl", "copy_to_dist_dir")
+
+def _register_module_to_map(module_map, name, path, config_option, srcs, config_srcs, deps, config_deps):
+    processed_config_srcs = {}
+    processed_config_deps = {}
+
+    for config_src_name in config_srcs:
+        config_src = config_srcs[config_src_name]
+
+        if type(config_src) == "list":
+            processed_config_srcs[config_src_name] = {True: config_src}
+        else:
+            processed_config_srcs[config_src_name] = config_src
+
+    for config_deps_name in config_deps:
+        config_dep = config_deps[config_deps_name]
+
+        if type(config_dep) == "list":
+            processed_config_deps[config_deps_name] = {True: config_dep}
+        else:
+            processed_config_deps[config_deps_name] = config_dep
+
+    module = struct(
+        name = name,
+        path = path,
+        srcs = srcs,
+        config_srcs = processed_config_srcs,
+        config_option = config_option,
+        deps = deps,
+        config_deps = processed_config_deps,
+    )
+
+    module_map[name] = module
+
+def _get_config_choices(map, options):
+    choices = []
+
+    for option in map:
+        choices.extend(map[option].get(option in options, []))
+
+    return choices
+
+def _get_kernel_build_options(modules, config_options):
+    all_options = {option: True for option in config_options}
+    all_options = all_options | {module.config_option: True for module in modules if module.config_option}
+
+    return all_options
+
+def _get_kernel_build_module_srcs(module, options, formatter):
+    srcs = module.srcs + _get_config_choices(module.config_srcs, options)
+    module_path = "{}/".format(module.path) if module.path else ""
+    globbed_srcs = native.glob(["{}{}".format(module_path, formatter(src)) for src in srcs])
+
+    return globbed_srcs
+
+def _get_kernel_build_module_deps(module, options, formatter):
+    deps = module.deps + _get_config_choices(module.config_deps, options)
+    deps = [formatter(dep) for dep in deps]
+
+    return deps
+
+def create_module_registry(hdrs = []):
+    module_map = {}
+
+    def register(name, path = None, config_option = None, srcs = [], config_srcs = {}, deps = [], config_deps = {}):
+        _register_module_to_map(module_map, name, path, config_option, srcs, config_srcs, deps, config_deps)
+
+    return struct(
+        register = register,
+        get = module_map.get,
+        hdrs = hdrs,
+        module_map = module_map,
+    )
+
+def define_target_variant_modules(target, variant, registry, modules, config_options = []):
+    kernel_build = "{}_{}".format(target, variant)
+    kernel_build_label = "//msm-kernel:{}".format(kernel_build)
+    modules = [registry.get(module_name) for module_name in modules]
+    options = _get_kernel_build_options(modules, config_options)
+    build_print = lambda message: print("{}: {}".format(kernel_build, message))
+    formatter = lambda s: s.replace("%b", kernel_build).replace("%t", target)
+
+    headers = ["//msm-kernel:all_headers"] + registry.hdrs
+    all_module_rules = []
+
+    for module in modules:
+        rule_name = "{}_{}".format(kernel_build, module.name)
+        module_srcs = _get_kernel_build_module_srcs(module, options, formatter)
+
+        if not module_srcs:
+            continue
+
+        ddk_submodule(
+            name = rule_name,
+            srcs = module_srcs,
+            out = "{}.ko".format(module.name),
+            deps = headers + _get_kernel_build_module_deps(module, options, formatter),
+            local_defines = options.keys(),
+        )
+
+        all_module_rules.append(rule_name)
+
+    ddk_module(
+        name = "{}_modules".format(kernel_build),
+        kernel_build = kernel_build_label,
+        deps = all_module_rules,
+    )
+
+    copy_to_dist_dir(
+        name = "{}_modules_dist".format(kernel_build),
+        data = [":{}_modules".format(kernel_build)],
+        dist_dir = "out/target/product/{}/dlkm/lib/modules/".format(kernel_build),
+        flat = True,
+        wipe_dist_dir = False,
+        allow_duplicate_filenames = False,
+        mode_overrides = {"**/*": "644"},
+    )
+
+def define_consolidate_gki_modules(target, registry, modules, config_options = []):
+    define_target_variant_modules(target, "consolidate", registry, modules, config_options)
+    define_target_variant_modules(target, "gki", registry, modules, config_options)

+ 25 - 0
synx_modules.bzl

@@ -0,0 +1,25 @@
+load(":synx_module_build.bzl", "create_module_registry")
+
+SYNX_KERNEL_ROOT = "synx-kernel"
+
+synx_modules = create_module_registry([":synx_headers"])
+register_synx_module = synx_modules.register
+
+register_synx_module(
+    name = "synx",
+    path = "msm",
+    srcs = [
+        "synx/synx.c",
+        "synx/synx_global.c",
+        "synx/synx_util.c",
+        "synx/synx_debugfs.c",
+    ],
+)
+
+register_synx_module(
+    name = "ipclite",
+    path = "msm",
+    srcs = [
+        "synx/ipclite.c",
+    ],
+)

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác