1 /* $NetBSD: qxl_debugfs.c,v 1.2 2018/08/27 04:58:35 riastradh Exp $ */ 2 3 /* 4 * Copyright (C) 2009 Red Hat <bskeggs@redhat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial 16 * portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 */ 27 28 /* 29 * Authors: 30 * Alon Levy <alevy@redhat.com> 31 */ 32 33 #include <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: qxl_debugfs.c,v 1.2 2018/08/27 04:58:35 riastradh Exp $"); 35 36 #include <linux/debugfs.h> 37 38 #include "drmP.h" 39 #include "qxl_drv.h" 40 #include "qxl_object.h" 41 42 43 #if defined(CONFIG_DEBUG_FS) 44 static int 45 qxl_debugfs_irq_received(struct seq_file *m, void *data) 46 { 47 struct drm_info_node *node = (struct drm_info_node *) m->private; 48 struct qxl_device *qdev = node->minor->dev->dev_private; 49 50 seq_printf(m, "%d\n", atomic_read(&qdev->irq_received)); 51 seq_printf(m, "%d\n", atomic_read(&qdev->irq_received_display)); 52 seq_printf(m, "%d\n", atomic_read(&qdev->irq_received_cursor)); 53 seq_printf(m, "%d\n", atomic_read(&qdev->irq_received_io_cmd)); 54 seq_printf(m, "%d\n", qdev->irq_received_error); 55 return 0; 56 } 57 58 static int 59 qxl_debugfs_buffers_info(struct seq_file *m, void *data) 60 { 61 struct drm_info_node *node = (struct drm_info_node *) m->private; 62 struct qxl_device *qdev = node->minor->dev->dev_private; 63 struct qxl_bo *bo; 64 65 list_for_each_entry(bo, &qdev->gem.objects, list) { 66 struct reservation_object_list *fobj; 67 int rel; 68 69 rcu_read_lock(); 70 fobj = rcu_dereference(bo->tbo.resv->fence); 71 rel = fobj ? fobj->shared_count : 0; 72 rcu_read_unlock(); 73 74 seq_printf(m, "size %ld, pc %d, num releases %d\n", 75 (unsigned long)bo->gem_base.size, 76 bo->pin_count, rel); 77 } 78 return 0; 79 } 80 81 static struct drm_info_list qxl_debugfs_list[] = { 82 { "irq_received", qxl_debugfs_irq_received, 0, NULL }, 83 { "qxl_buffers", qxl_debugfs_buffers_info, 0, NULL }, 84 }; 85 #define QXL_DEBUGFS_ENTRIES ARRAY_SIZE(qxl_debugfs_list) 86 #endif 87 88 int 89 qxl_debugfs_init(struct drm_minor *minor) 90 { 91 #if defined(CONFIG_DEBUG_FS) 92 drm_debugfs_create_files(qxl_debugfs_list, QXL_DEBUGFS_ENTRIES, 93 minor->debugfs_root, minor); 94 #endif 95 return 0; 96 } 97 98 void 99 qxl_debugfs_takedown(struct drm_minor *minor) 100 { 101 #if defined(CONFIG_DEBUG_FS) 102 drm_debugfs_remove_files(qxl_debugfs_list, QXL_DEBUGFS_ENTRIES, 103 minor); 104 #endif 105 } 106 107 int qxl_debugfs_add_files(struct qxl_device *qdev, 108 struct drm_info_list *files, 109 unsigned nfiles) 110 { 111 unsigned i; 112 113 for (i = 0; i < qdev->debugfs_count; i++) { 114 if (qdev->debugfs[i].files == files) { 115 /* Already registered */ 116 return 0; 117 } 118 } 119 120 i = qdev->debugfs_count + 1; 121 if (i > QXL_DEBUGFS_MAX_COMPONENTS) { 122 DRM_ERROR("Reached maximum number of debugfs components.\n"); 123 DRM_ERROR("Report so we increase QXL_DEBUGFS_MAX_COMPONENTS.\n"); 124 return -EINVAL; 125 } 126 qdev->debugfs[qdev->debugfs_count].files = files; 127 qdev->debugfs[qdev->debugfs_count].num_files = nfiles; 128 qdev->debugfs_count = i; 129 #if defined(CONFIG_DEBUG_FS) 130 drm_debugfs_create_files(files, nfiles, 131 qdev->ddev->control->debugfs_root, 132 qdev->ddev->control); 133 drm_debugfs_create_files(files, nfiles, 134 qdev->ddev->primary->debugfs_root, 135 qdev->ddev->primary); 136 #endif 137 return 0; 138 } 139 140 void qxl_debugfs_remove_files(struct qxl_device *qdev) 141 { 142 #if defined(CONFIG_DEBUG_FS) 143 unsigned i; 144 145 for (i = 0; i < qdev->debugfs_count; i++) { 146 drm_debugfs_remove_files(qdev->debugfs[i].files, 147 qdev->debugfs[i].num_files, 148 qdev->ddev->control); 149 drm_debugfs_remove_files(qdev->debugfs[i].files, 150 qdev->debugfs[i].num_files, 151 qdev->ddev->primary); 152 } 153 #endif 154 } 155