xref: /OK3568_Linux_fs/kernel/drivers/usb/chipidea/debug.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun #include <linux/kernel.h>
3*4882a593Smuzhiyun #include <linux/device.h>
4*4882a593Smuzhiyun #include <linux/types.h>
5*4882a593Smuzhiyun #include <linux/spinlock.h>
6*4882a593Smuzhiyun #include <linux/debugfs.h>
7*4882a593Smuzhiyun #include <linux/seq_file.h>
8*4882a593Smuzhiyun #include <linux/uaccess.h>
9*4882a593Smuzhiyun #include <linux/usb/ch9.h>
10*4882a593Smuzhiyun #include <linux/usb/gadget.h>
11*4882a593Smuzhiyun #include <linux/usb/phy.h>
12*4882a593Smuzhiyun #include <linux/usb/otg.h>
13*4882a593Smuzhiyun #include <linux/usb/otg-fsm.h>
14*4882a593Smuzhiyun #include <linux/usb/chipidea.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include "ci.h"
17*4882a593Smuzhiyun #include "udc.h"
18*4882a593Smuzhiyun #include "bits.h"
19*4882a593Smuzhiyun #include "otg.h"
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun /*
22*4882a593Smuzhiyun  * ci_device_show: prints information about device capabilities and status
23*4882a593Smuzhiyun  */
ci_device_show(struct seq_file * s,void * data)24*4882a593Smuzhiyun static int ci_device_show(struct seq_file *s, void *data)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	struct ci_hdrc *ci = s->private;
27*4882a593Smuzhiyun 	struct usb_gadget *gadget = &ci->gadget;
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun 	seq_printf(s, "speed             = %d\n", gadget->speed);
30*4882a593Smuzhiyun 	seq_printf(s, "max_speed         = %d\n", gadget->max_speed);
31*4882a593Smuzhiyun 	seq_printf(s, "is_otg            = %d\n", gadget->is_otg);
32*4882a593Smuzhiyun 	seq_printf(s, "is_a_peripheral   = %d\n", gadget->is_a_peripheral);
33*4882a593Smuzhiyun 	seq_printf(s, "b_hnp_enable      = %d\n", gadget->b_hnp_enable);
34*4882a593Smuzhiyun 	seq_printf(s, "a_hnp_support     = %d\n", gadget->a_hnp_support);
35*4882a593Smuzhiyun 	seq_printf(s, "a_alt_hnp_support = %d\n", gadget->a_alt_hnp_support);
36*4882a593Smuzhiyun 	seq_printf(s, "name              = %s\n",
37*4882a593Smuzhiyun 		   (gadget->name ? gadget->name : ""));
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 	if (!ci->driver)
40*4882a593Smuzhiyun 		return 0;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 	seq_printf(s, "gadget function   = %s\n",
43*4882a593Smuzhiyun 		       (ci->driver->function ? ci->driver->function : ""));
44*4882a593Smuzhiyun 	seq_printf(s, "gadget max speed  = %d\n", ci->driver->max_speed);
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	return 0;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun DEFINE_SHOW_ATTRIBUTE(ci_device);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun /*
51*4882a593Smuzhiyun  * ci_port_test_show: reads port test mode
52*4882a593Smuzhiyun  */
ci_port_test_show(struct seq_file * s,void * data)53*4882a593Smuzhiyun static int ci_port_test_show(struct seq_file *s, void *data)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun 	struct ci_hdrc *ci = s->private;
56*4882a593Smuzhiyun 	unsigned long flags;
57*4882a593Smuzhiyun 	unsigned mode;
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	pm_runtime_get_sync(ci->dev);
60*4882a593Smuzhiyun 	spin_lock_irqsave(&ci->lock, flags);
61*4882a593Smuzhiyun 	mode = hw_port_test_get(ci);
62*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ci->lock, flags);
63*4882a593Smuzhiyun 	pm_runtime_put_sync(ci->dev);
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	seq_printf(s, "mode = %u\n", mode);
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	return 0;
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /*
71*4882a593Smuzhiyun  * ci_port_test_write: writes port test mode
72*4882a593Smuzhiyun  */
ci_port_test_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)73*4882a593Smuzhiyun static ssize_t ci_port_test_write(struct file *file, const char __user *ubuf,
74*4882a593Smuzhiyun 				  size_t count, loff_t *ppos)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun 	struct seq_file *s = file->private_data;
77*4882a593Smuzhiyun 	struct ci_hdrc *ci = s->private;
78*4882a593Smuzhiyun 	unsigned long flags;
79*4882a593Smuzhiyun 	unsigned mode;
80*4882a593Smuzhiyun 	char buf[32];
81*4882a593Smuzhiyun 	int ret;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	count = min_t(size_t, sizeof(buf) - 1, count);
84*4882a593Smuzhiyun 	if (copy_from_user(buf, ubuf, count))
85*4882a593Smuzhiyun 		return -EFAULT;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	/* sscanf requires a zero terminated string */
88*4882a593Smuzhiyun 	buf[count] = '\0';
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	if (sscanf(buf, "%u", &mode) != 1)
91*4882a593Smuzhiyun 		return -EINVAL;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	if (mode > 255)
94*4882a593Smuzhiyun 		return -EBADRQC;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	pm_runtime_get_sync(ci->dev);
97*4882a593Smuzhiyun 	spin_lock_irqsave(&ci->lock, flags);
98*4882a593Smuzhiyun 	ret = hw_port_test_set(ci, mode);
99*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ci->lock, flags);
100*4882a593Smuzhiyun 	pm_runtime_put_sync(ci->dev);
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	return ret ? ret : count;
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun 
ci_port_test_open(struct inode * inode,struct file * file)105*4882a593Smuzhiyun static int ci_port_test_open(struct inode *inode, struct file *file)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun 	return single_open(file, ci_port_test_show, inode->i_private);
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun static const struct file_operations ci_port_test_fops = {
111*4882a593Smuzhiyun 	.open		= ci_port_test_open,
112*4882a593Smuzhiyun 	.write		= ci_port_test_write,
113*4882a593Smuzhiyun 	.read		= seq_read,
114*4882a593Smuzhiyun 	.llseek		= seq_lseek,
115*4882a593Smuzhiyun 	.release	= single_release,
116*4882a593Smuzhiyun };
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun /*
119*4882a593Smuzhiyun  * ci_qheads_show: DMA contents of all queue heads
120*4882a593Smuzhiyun  */
ci_qheads_show(struct seq_file * s,void * data)121*4882a593Smuzhiyun static int ci_qheads_show(struct seq_file *s, void *data)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun 	struct ci_hdrc *ci = s->private;
124*4882a593Smuzhiyun 	unsigned long flags;
125*4882a593Smuzhiyun 	unsigned i, j;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	if (ci->role != CI_ROLE_GADGET) {
128*4882a593Smuzhiyun 		seq_printf(s, "not in gadget mode\n");
129*4882a593Smuzhiyun 		return 0;
130*4882a593Smuzhiyun 	}
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	spin_lock_irqsave(&ci->lock, flags);
133*4882a593Smuzhiyun 	for (i = 0; i < ci->hw_ep_max/2; i++) {
134*4882a593Smuzhiyun 		struct ci_hw_ep *hweprx = &ci->ci_hw_ep[i];
135*4882a593Smuzhiyun 		struct ci_hw_ep *hweptx =
136*4882a593Smuzhiyun 			&ci->ci_hw_ep[i + ci->hw_ep_max/2];
137*4882a593Smuzhiyun 		seq_printf(s, "EP=%02i: RX=%08X TX=%08X\n",
138*4882a593Smuzhiyun 			   i, (u32)hweprx->qh.dma, (u32)hweptx->qh.dma);
139*4882a593Smuzhiyun 		for (j = 0; j < (sizeof(struct ci_hw_qh)/sizeof(u32)); j++)
140*4882a593Smuzhiyun 			seq_printf(s, " %04X:    %08X    %08X\n", j,
141*4882a593Smuzhiyun 				   *((u32 *)hweprx->qh.ptr + j),
142*4882a593Smuzhiyun 				   *((u32 *)hweptx->qh.ptr + j));
143*4882a593Smuzhiyun 	}
144*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ci->lock, flags);
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	return 0;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun DEFINE_SHOW_ATTRIBUTE(ci_qheads);
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun /*
151*4882a593Smuzhiyun  * ci_requests_show: DMA contents of all requests currently queued (all endpts)
152*4882a593Smuzhiyun  */
ci_requests_show(struct seq_file * s,void * data)153*4882a593Smuzhiyun static int ci_requests_show(struct seq_file *s, void *data)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun 	struct ci_hdrc *ci = s->private;
156*4882a593Smuzhiyun 	unsigned long flags;
157*4882a593Smuzhiyun 	struct ci_hw_req *req = NULL;
158*4882a593Smuzhiyun 	struct td_node *node, *tmpnode;
159*4882a593Smuzhiyun 	unsigned i, j, qsize = sizeof(struct ci_hw_td)/sizeof(u32);
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	if (ci->role != CI_ROLE_GADGET) {
162*4882a593Smuzhiyun 		seq_printf(s, "not in gadget mode\n");
163*4882a593Smuzhiyun 		return 0;
164*4882a593Smuzhiyun 	}
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	spin_lock_irqsave(&ci->lock, flags);
167*4882a593Smuzhiyun 	for (i = 0; i < ci->hw_ep_max; i++)
168*4882a593Smuzhiyun 		list_for_each_entry(req, &ci->ci_hw_ep[i].qh.queue, queue) {
169*4882a593Smuzhiyun 			list_for_each_entry_safe(node, tmpnode, &req->tds, td) {
170*4882a593Smuzhiyun 				seq_printf(s, "EP=%02i: TD=%08X %s\n",
171*4882a593Smuzhiyun 					   i % (ci->hw_ep_max / 2),
172*4882a593Smuzhiyun 					   (u32)node->dma,
173*4882a593Smuzhiyun 					   ((i < ci->hw_ep_max/2) ?
174*4882a593Smuzhiyun 					   "RX" : "TX"));
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 				for (j = 0; j < qsize; j++)
177*4882a593Smuzhiyun 					seq_printf(s, " %04X:    %08X\n", j,
178*4882a593Smuzhiyun 						   *((u32 *)node->ptr + j));
179*4882a593Smuzhiyun 			}
180*4882a593Smuzhiyun 		}
181*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ci->lock, flags);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	return 0;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun DEFINE_SHOW_ATTRIBUTE(ci_requests);
186*4882a593Smuzhiyun 
ci_otg_show(struct seq_file * s,void * unused)187*4882a593Smuzhiyun static int ci_otg_show(struct seq_file *s, void *unused)
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun 	struct ci_hdrc *ci = s->private;
190*4882a593Smuzhiyun 	struct otg_fsm *fsm;
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	if (!ci || !ci_otg_is_fsm_mode(ci))
193*4882a593Smuzhiyun 		return 0;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	fsm = &ci->fsm;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	/* ------ State ----- */
198*4882a593Smuzhiyun 	seq_printf(s, "OTG state: %s\n\n",
199*4882a593Smuzhiyun 			usb_otg_state_string(ci->otg.state));
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	/* ------ State Machine Variables ----- */
202*4882a593Smuzhiyun 	seq_printf(s, "a_bus_drop: %d\n", fsm->a_bus_drop);
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	seq_printf(s, "a_bus_req: %d\n", fsm->a_bus_req);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	seq_printf(s, "a_srp_det: %d\n", fsm->a_srp_det);
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	seq_printf(s, "a_vbus_vld: %d\n", fsm->a_vbus_vld);
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	seq_printf(s, "b_conn: %d\n", fsm->b_conn);
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	seq_printf(s, "adp_change: %d\n", fsm->adp_change);
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	seq_printf(s, "power_up: %d\n", fsm->power_up);
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	seq_printf(s, "a_bus_resume: %d\n", fsm->a_bus_resume);
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	seq_printf(s, "a_bus_suspend: %d\n", fsm->a_bus_suspend);
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	seq_printf(s, "a_conn: %d\n", fsm->a_conn);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	seq_printf(s, "b_bus_req: %d\n", fsm->b_bus_req);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	seq_printf(s, "b_bus_suspend: %d\n", fsm->b_bus_suspend);
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	seq_printf(s, "b_se0_srp: %d\n", fsm->b_se0_srp);
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	seq_printf(s, "b_ssend_srp: %d\n", fsm->b_ssend_srp);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	seq_printf(s, "b_sess_vld: %d\n", fsm->b_sess_vld);
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	seq_printf(s, "b_srp_done: %d\n", fsm->b_srp_done);
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	seq_printf(s, "drv_vbus: %d\n", fsm->drv_vbus);
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	seq_printf(s, "loc_conn: %d\n", fsm->loc_conn);
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	seq_printf(s, "loc_sof: %d\n", fsm->loc_sof);
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	seq_printf(s, "adp_prb: %d\n", fsm->adp_prb);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	seq_printf(s, "id: %d\n", fsm->id);
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	seq_printf(s, "protocol: %d\n", fsm->protocol);
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	return 0;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun DEFINE_SHOW_ATTRIBUTE(ci_otg);
249*4882a593Smuzhiyun 
ci_role_show(struct seq_file * s,void * data)250*4882a593Smuzhiyun static int ci_role_show(struct seq_file *s, void *data)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun 	struct ci_hdrc *ci = s->private;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	if (ci->role != CI_ROLE_END)
255*4882a593Smuzhiyun 		seq_printf(s, "%s\n", ci_role(ci)->name);
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	return 0;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun 
ci_role_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)260*4882a593Smuzhiyun static ssize_t ci_role_write(struct file *file, const char __user *ubuf,
261*4882a593Smuzhiyun 			     size_t count, loff_t *ppos)
262*4882a593Smuzhiyun {
263*4882a593Smuzhiyun 	struct seq_file *s = file->private_data;
264*4882a593Smuzhiyun 	struct ci_hdrc *ci = s->private;
265*4882a593Smuzhiyun 	enum ci_role role;
266*4882a593Smuzhiyun 	char buf[8];
267*4882a593Smuzhiyun 	int ret;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
270*4882a593Smuzhiyun 		return -EFAULT;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	for (role = CI_ROLE_HOST; role < CI_ROLE_END; role++)
273*4882a593Smuzhiyun 		if (ci->roles[role] &&
274*4882a593Smuzhiyun 		    !strncmp(buf, ci->roles[role]->name,
275*4882a593Smuzhiyun 			     strlen(ci->roles[role]->name)))
276*4882a593Smuzhiyun 			break;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	if (role == CI_ROLE_END || role == ci->role)
279*4882a593Smuzhiyun 		return -EINVAL;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	pm_runtime_get_sync(ci->dev);
282*4882a593Smuzhiyun 	disable_irq(ci->irq);
283*4882a593Smuzhiyun 	ci_role_stop(ci);
284*4882a593Smuzhiyun 	ret = ci_role_start(ci, role);
285*4882a593Smuzhiyun 	enable_irq(ci->irq);
286*4882a593Smuzhiyun 	pm_runtime_put_sync(ci->dev);
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	return ret ? ret : count;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun 
ci_role_open(struct inode * inode,struct file * file)291*4882a593Smuzhiyun static int ci_role_open(struct inode *inode, struct file *file)
292*4882a593Smuzhiyun {
293*4882a593Smuzhiyun 	return single_open(file, ci_role_show, inode->i_private);
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun static const struct file_operations ci_role_fops = {
297*4882a593Smuzhiyun 	.open		= ci_role_open,
298*4882a593Smuzhiyun 	.write		= ci_role_write,
299*4882a593Smuzhiyun 	.read		= seq_read,
300*4882a593Smuzhiyun 	.llseek		= seq_lseek,
301*4882a593Smuzhiyun 	.release	= single_release,
302*4882a593Smuzhiyun };
303*4882a593Smuzhiyun 
ci_registers_show(struct seq_file * s,void * unused)304*4882a593Smuzhiyun static int ci_registers_show(struct seq_file *s, void *unused)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun 	struct ci_hdrc *ci = s->private;
307*4882a593Smuzhiyun 	u32 tmp_reg;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	if (!ci || ci->in_lpm)
310*4882a593Smuzhiyun 		return -EPERM;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	/* ------ Registers ----- */
313*4882a593Smuzhiyun 	tmp_reg = hw_read_intr_enable(ci);
314*4882a593Smuzhiyun 	seq_printf(s, "USBINTR reg: %08x\n", tmp_reg);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	tmp_reg = hw_read_intr_status(ci);
317*4882a593Smuzhiyun 	seq_printf(s, "USBSTS reg: %08x\n", tmp_reg);
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	tmp_reg = hw_read(ci, OP_USBMODE, ~0);
320*4882a593Smuzhiyun 	seq_printf(s, "USBMODE reg: %08x\n", tmp_reg);
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	tmp_reg = hw_read(ci, OP_USBCMD, ~0);
323*4882a593Smuzhiyun 	seq_printf(s, "USBCMD reg: %08x\n", tmp_reg);
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	tmp_reg = hw_read(ci, OP_PORTSC, ~0);
326*4882a593Smuzhiyun 	seq_printf(s, "PORTSC reg: %08x\n", tmp_reg);
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	if (ci->is_otg) {
329*4882a593Smuzhiyun 		tmp_reg = hw_read_otgsc(ci, ~0);
330*4882a593Smuzhiyun 		seq_printf(s, "OTGSC reg: %08x\n", tmp_reg);
331*4882a593Smuzhiyun 	}
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	return 0;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun DEFINE_SHOW_ATTRIBUTE(ci_registers);
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun /**
338*4882a593Smuzhiyun  * dbg_create_files: initializes the attribute interface
339*4882a593Smuzhiyun  * @ci: device
340*4882a593Smuzhiyun  *
341*4882a593Smuzhiyun  * This function returns an error code
342*4882a593Smuzhiyun  */
dbg_create_files(struct ci_hdrc * ci)343*4882a593Smuzhiyun void dbg_create_files(struct ci_hdrc *ci)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun 	ci->debugfs = debugfs_create_dir(dev_name(ci->dev), usb_debug_root);
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	debugfs_create_file("device", S_IRUGO, ci->debugfs, ci,
348*4882a593Smuzhiyun 			    &ci_device_fops);
349*4882a593Smuzhiyun 	debugfs_create_file("port_test", S_IRUGO | S_IWUSR, ci->debugfs, ci,
350*4882a593Smuzhiyun 			    &ci_port_test_fops);
351*4882a593Smuzhiyun 	debugfs_create_file("qheads", S_IRUGO, ci->debugfs, ci,
352*4882a593Smuzhiyun 			    &ci_qheads_fops);
353*4882a593Smuzhiyun 	debugfs_create_file("requests", S_IRUGO, ci->debugfs, ci,
354*4882a593Smuzhiyun 			    &ci_requests_fops);
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	if (ci_otg_is_fsm_mode(ci)) {
357*4882a593Smuzhiyun 		debugfs_create_file("otg", S_IRUGO, ci->debugfs, ci,
358*4882a593Smuzhiyun 				    &ci_otg_fops);
359*4882a593Smuzhiyun 	}
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	debugfs_create_file("role", S_IRUGO | S_IWUSR, ci->debugfs, ci,
362*4882a593Smuzhiyun 			    &ci_role_fops);
363*4882a593Smuzhiyun 	debugfs_create_file("registers", S_IRUGO, ci->debugfs, ci,
364*4882a593Smuzhiyun 			    &ci_registers_fops);
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun /**
368*4882a593Smuzhiyun  * dbg_remove_files: destroys the attribute interface
369*4882a593Smuzhiyun  * @ci: device
370*4882a593Smuzhiyun  */
dbg_remove_files(struct ci_hdrc * ci)371*4882a593Smuzhiyun void dbg_remove_files(struct ci_hdrc *ci)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	debugfs_remove_recursive(ci->debugfs);
374*4882a593Smuzhiyun }
375