Loading drivers/media/platform/msm/synx/Makefile +1 −1 Original line number Diff line number Diff line # SPDX-License-Identifier: GPL-2.0-only ccflags-$(CONFIG_SPECTRA_CAMERA) += -Idrivers/media/platform/msm/camera/cam_sync obj-$(CONFIG_MSM_GLOBAL_SYNX) += synx.o synx_util.o obj-$(CONFIG_MSM_GLOBAL_SYNX) += synx.o synx_util.o synx_debugfs.o drivers/media/platform/msm/synx/synx.c +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include "synx_api.h" #include "synx_util.h" #include "synx_debugfs.h" struct synx_device *synx_dev; Loading Loading @@ -1478,6 +1479,8 @@ static int __init synx_init(void) INIT_LIST_HEAD(&synx_dev->client_list); synx_dev->dma_context = dma_fence_context_alloc(1); synx_dev->debugfs_root = init_synx_debug_dir(synx_dev); synx_bind_ops_register(synx_dev); pr_info("synx device init success\n"); Loading drivers/media/platform/msm/synx/synx_debugfs.c 0 → 100644 +192 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2019, The Linux Foundation. All rights reserved. */ #include <linux/io.h> #include <linux/module.h> #include <linux/debugfs.h> #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/list.h> #include "synx_api.h" #include "synx_private.h" #include "synx_util.h" #include "synx_debugfs.h" #define MAX_DBG_BUF_SIZE (36 * SYNX_MAX_OBJS) struct dentry *my_direc; const char delim[] = ","; int columns = NAME_COLUMN | ID_COLUMN | BOUND_COLUMN | STATE_COLUMN | ERROR_CODES; void populate_bound_rows( struct synx_table_row *row, char *cur, char *end) { int j; int state = SYNX_STATE_INVALID; for (j = 0; j < row->num_bound_synxs; j++) { cur += scnprintf(cur, end - cur, "\n\tID: %d State: %s", row->bound_synxs[j].external_data->synx_obj, state); } } static ssize_t synx_table_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct synx_device *dev = file->private_data; struct error_node *err_node, *err_node_tmp; struct synx_table_row *row; char *dbuf, *cur, *end; int i = 0; int state = SYNX_STATE_INVALID; ssize_t len = 0; dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL); if (!dbuf) return -ENOMEM; cur = dbuf; end = cur + MAX_DBG_BUF_SIZE; if (columns & NAME_COLUMN) cur += scnprintf(cur, end - cur, "| Name |"); if (columns & ID_COLUMN) cur += scnprintf(cur, end - cur, "| ID |"); if (columns & BOUND_COLUMN) cur += scnprintf(cur, end - cur, "| Bound |"); if (columns & STATE_COLUMN) cur += scnprintf(cur, end - cur, "| Status |"); cur += scnprintf(cur, end - cur, "\n"); for (i = 0; i < SYNX_MAX_OBJS; i++) { row = &dev->synx_table[i]; if (!row || !row->synx_obj) continue; spin_lock_bh(&dev->row_spinlocks[row->index]); if (columns & NAME_COLUMN) cur += scnprintf(cur, end - cur, "|%10s|", row->name); if (columns & ID_COLUMN) cur += scnprintf(cur, end - cur, "|%10d|", row->synx_obj); if (columns & BOUND_COLUMN) cur += scnprintf(cur, end - cur, "|%11d|", row->num_bound_synxs); if (columns & STATE_COLUMN) { state = synx_status_locked(row); cur += scnprintf(cur, end - cur, "|%10d|", state); } if ((columns & BOUND_COLUMN) && (row->num_bound_synxs > 0)) { cur += scnprintf( cur, end - cur, "\nBound synx: "); populate_bound_rows(row, cur, end); } spin_unlock_bh(&dev->row_spinlocks[row->index]); cur += scnprintf(cur, end - cur, "\n"); } if (columns & ERROR_CODES && !list_empty( &synx_dev->synx_debug_head)) { cur += scnprintf( cur, end - cur, "\nError(s): "); spin_lock_bh(&synx_dev->synx_node_list_lock); list_for_each_entry_safe( err_node, err_node_tmp, &synx_dev->synx_debug_head, node) { if (err_node->timestamp != NULL) { cur += scnprintf(cur, end - cur, "\n\tTime: %s - ID: %d - Code: %d", err_node->timestamp, err_node->synx_obj, err_node->error_code); } list_del(&err_node->node); kfree(err_node); } spin_unlock_bh(&synx_dev->synx_node_list_lock); } cur += scnprintf(cur, end - cur, "\n=================================================\n"); len = simple_read_from_buffer(buf, count, ppos, dbuf, cur - dbuf); kfree(dbuf); return len; } static ssize_t synx_table_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { char *ptr; char *kbuffer = kzalloc(48, GFP_KERNEL); int stat = -1; if (!kbuffer) return -ENOMEM; stat = copy_from_user(kbuffer, buf, 48); if (stat != 0) { kfree(kbuffer); return -EFAULT; } while ((ptr = strsep(&kbuffer, delim)) != NULL) { ptr += '\0'; if (strcmp(ptr, "bound\n") == 0) columns = columns ^ BOUND_COLUMN; else if (strcmp(ptr, "name\n") == 0) columns = columns ^ NAME_COLUMN; else if (strcmp(ptr, "synxid\n") == 0) columns = columns ^ ID_COLUMN; else if (strcmp(ptr, "status\n") == 0) columns = columns ^ STATE_COLUMN; else if (strcmp(ptr, "errors\n") == 0) columns = columns ^ ERROR_CODES; } kfree(kbuffer); return count; } static const struct file_operations synx_table_fops = { .owner = THIS_MODULE, .read = synx_table_read, .write = synx_table_write, .open = simple_open, }; struct dentry *init_synx_debug_dir(struct synx_device *dev) { struct dentry *dir = NULL; dir = debugfs_create_dir("synx_debug", NULL); if (!dir) { pr_debug("Failed to create debugfs for synx\n"); return NULL; } if (!debugfs_create_file("synx_table", 0644, dir, dev, &synx_table_fops)) { pr_debug("Failed to create debugfs file for synx\n"); return NULL; } spin_lock_init(&dev->synx_node_list_lock); INIT_LIST_HEAD(&dev->synx_debug_head); return dir; } drivers/media/platform/msm/synx/synx_debugfs.h 0 → 100644 +17 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019, The Linux Foundation. All rights reserved. */ #include <linux/debugfs.h> #include <linux/delay.h> #include "synx_private.h" struct dentry *init_synx_debug_dir(struct synx_device *dev); #define NAME_COLUMN 0x0001 #define ID_COLUMN 0x0002 #define BOUND_COLUMN 0x0004 #define STATE_COLUMN 0x0008 #define ERROR_CODES 0x8000 drivers/media/platform/msm/synx/synx_private.h +22 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include <linux/idr.h> #include <linux/workqueue.h> #define MAX_TIMESTAMP_SIZE 32 #define SYNX_OBJ_NAME_LEN 64 #define SYNX_MAX_OBJS 1024 #define SYNX_MAX_REF_COUNTS 2048 Loading Loading @@ -45,6 +46,21 @@ struct synx_bind_desc { struct synx_external_data *external_data; }; /** * struct error_node - Single error node related to a table_row * * @timestamp : Time that the error occurred * @error_code : Code related to the error * @node : List member used to append * this node to a linked list */ struct error_node { char timestamp[MAX_TIMESTAMP_SIZE]; s32 error_code; s32 synx_obj; struct list_head node; }; /** * struct synx_callback_info - Single node of information about a kernel * callback registered on a sync object Loading Loading @@ -158,6 +174,9 @@ struct bind_operations { * dma_context : dma context id * bind_vtbl : Table with bind ops for supported external sync objects * client_list : All the synx clients * debugfs_root : Root directory for debugfs * synx_node_head : list head for synx nodes * synx_node_list_lock : Spinlock for synx nodes */ struct synx_device { struct cdev cdev; Loading @@ -173,6 +192,9 @@ struct synx_device { u64 dma_context; struct bind_operations bind_vtbl[SYNX_MAX_BIND_TYPES]; struct list_head client_list; struct dentry *debugfs_root; struct list_head synx_debug_head; spinlock_t synx_node_list_lock; }; /** Loading Loading
drivers/media/platform/msm/synx/Makefile +1 −1 Original line number Diff line number Diff line # SPDX-License-Identifier: GPL-2.0-only ccflags-$(CONFIG_SPECTRA_CAMERA) += -Idrivers/media/platform/msm/camera/cam_sync obj-$(CONFIG_MSM_GLOBAL_SYNX) += synx.o synx_util.o obj-$(CONFIG_MSM_GLOBAL_SYNX) += synx.o synx_util.o synx_debugfs.o
drivers/media/platform/msm/synx/synx.c +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include "synx_api.h" #include "synx_util.h" #include "synx_debugfs.h" struct synx_device *synx_dev; Loading Loading @@ -1478,6 +1479,8 @@ static int __init synx_init(void) INIT_LIST_HEAD(&synx_dev->client_list); synx_dev->dma_context = dma_fence_context_alloc(1); synx_dev->debugfs_root = init_synx_debug_dir(synx_dev); synx_bind_ops_register(synx_dev); pr_info("synx device init success\n"); Loading
drivers/media/platform/msm/synx/synx_debugfs.c 0 → 100644 +192 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2019, The Linux Foundation. All rights reserved. */ #include <linux/io.h> #include <linux/module.h> #include <linux/debugfs.h> #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/list.h> #include "synx_api.h" #include "synx_private.h" #include "synx_util.h" #include "synx_debugfs.h" #define MAX_DBG_BUF_SIZE (36 * SYNX_MAX_OBJS) struct dentry *my_direc; const char delim[] = ","; int columns = NAME_COLUMN | ID_COLUMN | BOUND_COLUMN | STATE_COLUMN | ERROR_CODES; void populate_bound_rows( struct synx_table_row *row, char *cur, char *end) { int j; int state = SYNX_STATE_INVALID; for (j = 0; j < row->num_bound_synxs; j++) { cur += scnprintf(cur, end - cur, "\n\tID: %d State: %s", row->bound_synxs[j].external_data->synx_obj, state); } } static ssize_t synx_table_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct synx_device *dev = file->private_data; struct error_node *err_node, *err_node_tmp; struct synx_table_row *row; char *dbuf, *cur, *end; int i = 0; int state = SYNX_STATE_INVALID; ssize_t len = 0; dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL); if (!dbuf) return -ENOMEM; cur = dbuf; end = cur + MAX_DBG_BUF_SIZE; if (columns & NAME_COLUMN) cur += scnprintf(cur, end - cur, "| Name |"); if (columns & ID_COLUMN) cur += scnprintf(cur, end - cur, "| ID |"); if (columns & BOUND_COLUMN) cur += scnprintf(cur, end - cur, "| Bound |"); if (columns & STATE_COLUMN) cur += scnprintf(cur, end - cur, "| Status |"); cur += scnprintf(cur, end - cur, "\n"); for (i = 0; i < SYNX_MAX_OBJS; i++) { row = &dev->synx_table[i]; if (!row || !row->synx_obj) continue; spin_lock_bh(&dev->row_spinlocks[row->index]); if (columns & NAME_COLUMN) cur += scnprintf(cur, end - cur, "|%10s|", row->name); if (columns & ID_COLUMN) cur += scnprintf(cur, end - cur, "|%10d|", row->synx_obj); if (columns & BOUND_COLUMN) cur += scnprintf(cur, end - cur, "|%11d|", row->num_bound_synxs); if (columns & STATE_COLUMN) { state = synx_status_locked(row); cur += scnprintf(cur, end - cur, "|%10d|", state); } if ((columns & BOUND_COLUMN) && (row->num_bound_synxs > 0)) { cur += scnprintf( cur, end - cur, "\nBound synx: "); populate_bound_rows(row, cur, end); } spin_unlock_bh(&dev->row_spinlocks[row->index]); cur += scnprintf(cur, end - cur, "\n"); } if (columns & ERROR_CODES && !list_empty( &synx_dev->synx_debug_head)) { cur += scnprintf( cur, end - cur, "\nError(s): "); spin_lock_bh(&synx_dev->synx_node_list_lock); list_for_each_entry_safe( err_node, err_node_tmp, &synx_dev->synx_debug_head, node) { if (err_node->timestamp != NULL) { cur += scnprintf(cur, end - cur, "\n\tTime: %s - ID: %d - Code: %d", err_node->timestamp, err_node->synx_obj, err_node->error_code); } list_del(&err_node->node); kfree(err_node); } spin_unlock_bh(&synx_dev->synx_node_list_lock); } cur += scnprintf(cur, end - cur, "\n=================================================\n"); len = simple_read_from_buffer(buf, count, ppos, dbuf, cur - dbuf); kfree(dbuf); return len; } static ssize_t synx_table_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { char *ptr; char *kbuffer = kzalloc(48, GFP_KERNEL); int stat = -1; if (!kbuffer) return -ENOMEM; stat = copy_from_user(kbuffer, buf, 48); if (stat != 0) { kfree(kbuffer); return -EFAULT; } while ((ptr = strsep(&kbuffer, delim)) != NULL) { ptr += '\0'; if (strcmp(ptr, "bound\n") == 0) columns = columns ^ BOUND_COLUMN; else if (strcmp(ptr, "name\n") == 0) columns = columns ^ NAME_COLUMN; else if (strcmp(ptr, "synxid\n") == 0) columns = columns ^ ID_COLUMN; else if (strcmp(ptr, "status\n") == 0) columns = columns ^ STATE_COLUMN; else if (strcmp(ptr, "errors\n") == 0) columns = columns ^ ERROR_CODES; } kfree(kbuffer); return count; } static const struct file_operations synx_table_fops = { .owner = THIS_MODULE, .read = synx_table_read, .write = synx_table_write, .open = simple_open, }; struct dentry *init_synx_debug_dir(struct synx_device *dev) { struct dentry *dir = NULL; dir = debugfs_create_dir("synx_debug", NULL); if (!dir) { pr_debug("Failed to create debugfs for synx\n"); return NULL; } if (!debugfs_create_file("synx_table", 0644, dir, dev, &synx_table_fops)) { pr_debug("Failed to create debugfs file for synx\n"); return NULL; } spin_lock_init(&dev->synx_node_list_lock); INIT_LIST_HEAD(&dev->synx_debug_head); return dir; }
drivers/media/platform/msm/synx/synx_debugfs.h 0 → 100644 +17 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019, The Linux Foundation. All rights reserved. */ #include <linux/debugfs.h> #include <linux/delay.h> #include "synx_private.h" struct dentry *init_synx_debug_dir(struct synx_device *dev); #define NAME_COLUMN 0x0001 #define ID_COLUMN 0x0002 #define BOUND_COLUMN 0x0004 #define STATE_COLUMN 0x0008 #define ERROR_CODES 0x8000
drivers/media/platform/msm/synx/synx_private.h +22 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include <linux/idr.h> #include <linux/workqueue.h> #define MAX_TIMESTAMP_SIZE 32 #define SYNX_OBJ_NAME_LEN 64 #define SYNX_MAX_OBJS 1024 #define SYNX_MAX_REF_COUNTS 2048 Loading Loading @@ -45,6 +46,21 @@ struct synx_bind_desc { struct synx_external_data *external_data; }; /** * struct error_node - Single error node related to a table_row * * @timestamp : Time that the error occurred * @error_code : Code related to the error * @node : List member used to append * this node to a linked list */ struct error_node { char timestamp[MAX_TIMESTAMP_SIZE]; s32 error_code; s32 synx_obj; struct list_head node; }; /** * struct synx_callback_info - Single node of information about a kernel * callback registered on a sync object Loading Loading @@ -158,6 +174,9 @@ struct bind_operations { * dma_context : dma context id * bind_vtbl : Table with bind ops for supported external sync objects * client_list : All the synx clients * debugfs_root : Root directory for debugfs * synx_node_head : list head for synx nodes * synx_node_list_lock : Spinlock for synx nodes */ struct synx_device { struct cdev cdev; Loading @@ -173,6 +192,9 @@ struct synx_device { u64 dma_context; struct bind_operations bind_vtbl[SYNX_MAX_BIND_TYPES]; struct list_head client_list; struct dentry *debugfs_root; struct list_head synx_debug_head; spinlock_t synx_node_list_lock; }; /** Loading