1 // SPDX-License-Identifier: GPL-2.0-only
3 /* Copyright (c) 2020, The Linux Foundation. All rights reserved. */
4 /* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. */
6 #include <linux/debugfs.h>
7 #include <linux/device.h>
9 #include <linux/list.h>
10 #include <linux/mhi.h>
11 #include <linux/mutex.h>
12 #include <linux/overflow.h>
13 #include <linux/pci.h>
14 #include <linux/seq_file.h>
15 #include <linux/sprintf.h>
16 #include <linux/string.h>
17 #include <linux/types.h>
18 #include <linux/workqueue.h>
21 #include "qaic_debugfs.h"
23 #define BOOTLOG_POOL_SIZE 16
24 #define BOOTLOG_MSG_SIZE 512
25 #define QAIC_DBC_DIR_NAME 9
28 /* Buffer for bootlog messages */
29 char str
[BOOTLOG_MSG_SIZE
];
30 /* Root struct of device, used to access device resources */
31 struct qaic_device
*qdev
;
32 /* Work struct to schedule work coming on QAIC_LOGGING channel */
33 struct work_struct work
;
37 /* Node in list of bootlog pages maintained by root device struct */
38 struct list_head node
;
39 /* Total size of the buffer that holds the bootlogs. It is PAGE_SIZE */
41 /* Offset for the next bootlog */
45 static int bootlog_show(struct seq_file
*s
, void *unused
)
47 struct bootlog_page
*page
;
48 struct qaic_device
*qdev
;
53 mutex_lock(&qdev
->bootlog_mutex
);
54 list_for_each_entry(page
, &qdev
->bootlog
, node
) {
56 page_end
= (void *)page
+ page
->offset
;
57 while (log
< page_end
) {
58 seq_printf(s
, "%s", (char *)log
);
59 log
+= strlen(log
) + 1;
62 mutex_unlock(&qdev
->bootlog_mutex
);
67 DEFINE_SHOW_ATTRIBUTE(bootlog
);
69 static int fifo_size_show(struct seq_file
*s
, void *unused
)
71 struct dma_bridge_chan
*dbc
= s
->private;
73 seq_printf(s
, "%u\n", dbc
->nelem
);
77 DEFINE_SHOW_ATTRIBUTE(fifo_size
);
79 static int queued_show(struct seq_file
*s
, void *unused
)
81 struct dma_bridge_chan
*dbc
= s
->private;
82 u32 tail
= 0, head
= 0;
84 qaic_data_get_fifo_info(dbc
, &head
, &tail
);
86 if (head
== U32_MAX
|| tail
== U32_MAX
)
87 seq_printf(s
, "%u\n", 0);
89 seq_printf(s
, "%u\n", dbc
->nelem
- head
+ tail
);
91 seq_printf(s
, "%u\n", tail
- head
);
96 DEFINE_SHOW_ATTRIBUTE(queued
);
98 void qaic_debugfs_init(struct qaic_drm_device
*qddev
)
100 struct qaic_device
*qdev
= qddev
->qdev
;
101 struct dentry
*debugfs_root
;
102 struct dentry
*debugfs_dir
;
103 char name
[QAIC_DBC_DIR_NAME
];
106 debugfs_root
= to_drm(qddev
)->debugfs_root
;
108 debugfs_create_file("bootlog", 0400, debugfs_root
, qdev
, &bootlog_fops
);
110 * 256 dbcs per device is likely the max we will ever see and lets static checking see a
113 for (i
= 0; i
< qdev
->num_dbc
&& i
< 256; ++i
) {
114 snprintf(name
, QAIC_DBC_DIR_NAME
, "dbc%03u", i
);
115 debugfs_dir
= debugfs_create_dir(name
, debugfs_root
);
116 debugfs_create_file("fifo_size", 0400, debugfs_dir
, &qdev
->dbc
[i
], &fifo_size_fops
);
117 debugfs_create_file("queued", 0400, debugfs_dir
, &qdev
->dbc
[i
], &queued_fops
);
121 static struct bootlog_page
*alloc_bootlog_page(struct qaic_device
*qdev
)
123 struct bootlog_page
*page
;
125 page
= (struct bootlog_page
*)devm_get_free_pages(&qdev
->pdev
->dev
, GFP_KERNEL
, 0);
129 page
->size
= PAGE_SIZE
;
130 page
->offset
= sizeof(*page
);
131 list_add_tail(&page
->node
, &qdev
->bootlog
);
136 static int reset_bootlog(struct qaic_device
*qdev
)
138 struct bootlog_page
*page
;
139 struct bootlog_page
*i
;
141 mutex_lock(&qdev
->bootlog_mutex
);
142 list_for_each_entry_safe(page
, i
, &qdev
->bootlog
, node
) {
143 list_del(&page
->node
);
144 devm_free_pages(&qdev
->pdev
->dev
, (unsigned long)page
);
147 page
= alloc_bootlog_page(qdev
);
148 mutex_unlock(&qdev
->bootlog_mutex
);
155 static void *bootlog_get_space(struct qaic_device
*qdev
, unsigned int size
)
157 struct bootlog_page
*page
;
159 page
= list_last_entry(&qdev
->bootlog
, struct bootlog_page
, node
);
161 if (size_add(size
, sizeof(*page
)) > page
->size
)
164 if (page
->offset
+ size
> page
->size
) {
165 page
= alloc_bootlog_page(qdev
);
170 return (void *)page
+ page
->offset
;
173 static void bootlog_commit(struct qaic_device
*qdev
, unsigned int size
)
175 struct bootlog_page
*page
;
177 page
= list_last_entry(&qdev
->bootlog
, struct bootlog_page
, node
);
179 page
->offset
+= size
;
182 static void bootlog_log(struct work_struct
*work
)
184 struct bootlog_msg
*msg
= container_of(work
, struct bootlog_msg
, work
);
185 unsigned int len
= strlen(msg
->str
) + 1;
186 struct qaic_device
*qdev
= msg
->qdev
;
189 mutex_lock(&qdev
->bootlog_mutex
);
190 log
= bootlog_get_space(qdev
, len
);
192 memcpy(log
, msg
, len
);
193 bootlog_commit(qdev
, len
);
195 mutex_unlock(&qdev
->bootlog_mutex
);
197 if (mhi_queue_buf(qdev
->bootlog_ch
, DMA_FROM_DEVICE
, msg
, BOOTLOG_MSG_SIZE
, MHI_EOT
))
198 devm_kfree(&qdev
->pdev
->dev
, msg
);
201 static int qaic_bootlog_mhi_probe(struct mhi_device
*mhi_dev
, const struct mhi_device_id
*id
)
203 struct qaic_device
*qdev
= pci_get_drvdata(to_pci_dev(mhi_dev
->mhi_cntrl
->cntrl_dev
));
204 struct bootlog_msg
*msg
;
207 qdev
->bootlog_wq
= alloc_ordered_workqueue("qaic_bootlog", 0);
208 if (!qdev
->bootlog_wq
) {
213 ret
= reset_bootlog(qdev
);
215 goto destroy_workqueue
;
217 ret
= mhi_prepare_for_transfer(mhi_dev
);
219 goto destroy_workqueue
;
221 for (i
= 0; i
< BOOTLOG_POOL_SIZE
; i
++) {
222 msg
= devm_kzalloc(&qdev
->pdev
->dev
, sizeof(*msg
), GFP_KERNEL
);
229 INIT_WORK(&msg
->work
, bootlog_log
);
231 ret
= mhi_queue_buf(mhi_dev
, DMA_FROM_DEVICE
, msg
, BOOTLOG_MSG_SIZE
, MHI_EOT
);
236 dev_set_drvdata(&mhi_dev
->dev
, qdev
);
237 qdev
->bootlog_ch
= mhi_dev
;
241 mhi_unprepare_from_transfer(mhi_dev
);
243 flush_workqueue(qdev
->bootlog_wq
);
244 destroy_workqueue(qdev
->bootlog_wq
);
249 static void qaic_bootlog_mhi_remove(struct mhi_device
*mhi_dev
)
251 struct qaic_device
*qdev
;
253 qdev
= dev_get_drvdata(&mhi_dev
->dev
);
255 mhi_unprepare_from_transfer(qdev
->bootlog_ch
);
256 flush_workqueue(qdev
->bootlog_wq
);
257 destroy_workqueue(qdev
->bootlog_wq
);
258 qdev
->bootlog_ch
= NULL
;
261 static void qaic_bootlog_mhi_ul_xfer_cb(struct mhi_device
*mhi_dev
, struct mhi_result
*mhi_result
)
265 static void qaic_bootlog_mhi_dl_xfer_cb(struct mhi_device
*mhi_dev
, struct mhi_result
*mhi_result
)
267 struct qaic_device
*qdev
= dev_get_drvdata(&mhi_dev
->dev
);
268 struct bootlog_msg
*msg
= mhi_result
->buf_addr
;
270 if (mhi_result
->transaction_status
) {
271 devm_kfree(&qdev
->pdev
->dev
, msg
);
275 /* Force a null at the end of the transferred string */
276 msg
->str
[mhi_result
->bytes_xferd
- 1] = 0;
278 queue_work(qdev
->bootlog_wq
, &msg
->work
);
281 static const struct mhi_device_id qaic_bootlog_mhi_match_table
[] = {
282 { .chan
= "QAIC_LOGGING", },
286 static struct mhi_driver qaic_bootlog_mhi_driver
= {
287 .id_table
= qaic_bootlog_mhi_match_table
,
288 .remove
= qaic_bootlog_mhi_remove
,
289 .probe
= qaic_bootlog_mhi_probe
,
290 .ul_xfer_cb
= qaic_bootlog_mhi_ul_xfer_cb
,
291 .dl_xfer_cb
= qaic_bootlog_mhi_dl_xfer_cb
,
293 .name
= "qaic_bootlog",
297 int qaic_bootlog_register(void)
299 return mhi_driver_register(&qaic_bootlog_mhi_driver
);
302 void qaic_bootlog_unregister(void)
304 mhi_driver_unregister(&qaic_bootlog_mhi_driver
);