diff options
-rw-r--r-- | drivers/usb/chipidea/ci.h | 2 | ||||
-rw-r--r-- | drivers/usb/chipidea/debug.c | 469 | ||||
-rw-r--r-- | drivers/usb/chipidea/debug.h | 9 | ||||
-rw-r--r-- | drivers/usb/chipidea/udc.c | 6 |
4 files changed, 151 insertions, 335 deletions
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index d738603a2757..c7d4622782ce 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h | |||
@@ -129,6 +129,7 @@ struct hw_bank { | |||
129 | * @vbus_active: is VBUS active | 129 | * @vbus_active: is VBUS active |
130 | * @transceiver: pointer to USB PHY, if any | 130 | * @transceiver: pointer to USB PHY, if any |
131 | * @hcd: pointer to usb_hcd for ehci host driver | 131 | * @hcd: pointer to usb_hcd for ehci host driver |
132 | * @debugfs: root dentry for this controller in debugfs | ||
132 | */ | 133 | */ |
133 | struct ci13xxx { | 134 | struct ci13xxx { |
134 | struct device *dev; | 135 | struct device *dev; |
@@ -164,6 +165,7 @@ struct ci13xxx { | |||
164 | bool global_phy; | 165 | bool global_phy; |
165 | struct usb_phy *transceiver; | 166 | struct usb_phy *transceiver; |
166 | struct usb_hcd *hcd; | 167 | struct usb_hcd *hcd; |
168 | struct dentry *debugfs; | ||
167 | }; | 169 | }; |
168 | 170 | ||
169 | static inline struct ci_role_driver *ci_role(struct ci13xxx *ci) | 171 | static inline struct ci_role_driver *ci_role(struct ci13xxx *ci) |
diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 898aca591915..057ae09025bf 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c | |||
@@ -2,6 +2,9 @@ | |||
2 | #include <linux/device.h> | 2 | #include <linux/device.h> |
3 | #include <linux/types.h> | 3 | #include <linux/types.h> |
4 | #include <linux/spinlock.h> | 4 | #include <linux/spinlock.h> |
5 | #include <linux/debugfs.h> | ||
6 | #include <linux/seq_file.h> | ||
7 | #include <linux/uaccess.h> | ||
5 | #include <linux/usb/ch9.h> | 8 | #include <linux/usb/ch9.h> |
6 | #include <linux/usb/gadget.h> | 9 | #include <linux/usb/gadget.h> |
7 | 10 | ||
@@ -11,223 +14,113 @@ | |||
11 | #include "debug.h" | 14 | #include "debug.h" |
12 | 15 | ||
13 | /** | 16 | /** |
14 | * hw_register_read: reads all device registers (execute without interruption) | 17 | * ci_device_show: prints information about device capabilities and status |
15 | * @buf: destination buffer | ||
16 | * @size: buffer size | ||
17 | * | ||
18 | * This function returns number of registers read | ||
19 | */ | 18 | */ |
20 | static size_t hw_register_read(struct ci13xxx *ci, u32 *buf, size_t size) | 19 | static int ci_device_show(struct seq_file *s, void *data) |
21 | { | 20 | { |
22 | unsigned i; | 21 | struct ci13xxx *ci = s->private; |
23 | 22 | struct usb_gadget *gadget = &ci->gadget; | |
24 | if (size > ci->hw_bank.size) | ||
25 | size = ci->hw_bank.size; | ||
26 | |||
27 | for (i = 0; i < size; i++) | ||
28 | buf[i] = hw_read(ci, i * sizeof(u32), ~0); | ||
29 | |||
30 | return size; | ||
31 | } | ||
32 | |||
33 | /** | ||
34 | * hw_register_write: writes to register | ||
35 | * @addr: register address | ||
36 | * @data: register value | ||
37 | * | ||
38 | * This function returns an error code | ||
39 | */ | ||
40 | static int hw_register_write(struct ci13xxx *ci, u16 addr, u32 data) | ||
41 | { | ||
42 | /* align */ | ||
43 | addr /= sizeof(u32); | ||
44 | 23 | ||
45 | if (addr >= ci->hw_bank.size) | 24 | seq_printf(s, "speed = %d\n", gadget->speed); |
46 | return -EINVAL; | 25 | seq_printf(s, "max_speed = %d\n", gadget->max_speed); |
26 | seq_printf(s, "is_otg = %d\n", gadget->is_otg); | ||
27 | seq_printf(s, "is_a_peripheral = %d\n", gadget->is_a_peripheral); | ||
28 | seq_printf(s, "b_hnp_enable = %d\n", gadget->b_hnp_enable); | ||
29 | seq_printf(s, "a_hnp_support = %d\n", gadget->a_hnp_support); | ||
30 | seq_printf(s, "a_alt_hnp_support = %d\n", gadget->a_alt_hnp_support); | ||
31 | seq_printf(s, "name = %s\n", | ||
32 | (gadget->name ? gadget->name : "")); | ||
33 | |||
34 | if (!ci->driver) | ||
35 | return 0; | ||
47 | 36 | ||
48 | /* align */ | 37 | seq_printf(s, "gadget function = %s\n", |
49 | addr *= sizeof(u32); | 38 | (ci->driver->function ? ci->driver->function : "")); |
39 | seq_printf(s, "gadget max speed = %d\n", ci->driver->max_speed); | ||
50 | 40 | ||
51 | hw_write(ci, addr, ~0, data); | ||
52 | return 0; | 41 | return 0; |
53 | } | 42 | } |
54 | 43 | ||
55 | /** | 44 | static int ci_device_open(struct inode *inode, struct file *file) |
56 | * hw_intr_clear: disables interrupt & clears interrupt status (execute without | ||
57 | * interruption) | ||
58 | * @n: interrupt bit | ||
59 | * | ||
60 | * This function returns an error code | ||
61 | */ | ||
62 | static int hw_intr_clear(struct ci13xxx *ci, int n) | ||
63 | { | 45 | { |
64 | if (n >= REG_BITS) | 46 | return single_open(file, ci_device_show, inode->i_private); |
65 | return -EINVAL; | ||
66 | |||
67 | hw_write(ci, OP_USBINTR, BIT(n), 0); | ||
68 | hw_write(ci, OP_USBSTS, BIT(n), BIT(n)); | ||
69 | return 0; | ||
70 | } | 47 | } |
71 | 48 | ||
72 | /** | 49 | static const struct file_operations ci_device_fops = { |
73 | * hw_intr_force: enables interrupt & forces interrupt status (execute without | 50 | .open = ci_device_open, |
74 | * interruption) | 51 | .read = seq_read, |
75 | * @n: interrupt bit | 52 | .llseek = seq_lseek, |
76 | * | 53 | .release = single_release, |
77 | * This function returns an error code | 54 | }; |
78 | */ | ||
79 | static int hw_intr_force(struct ci13xxx *ci, int n) | ||
80 | { | ||
81 | if (n >= REG_BITS) | ||
82 | return -EINVAL; | ||
83 | |||
84 | hw_write(ci, CAP_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE); | ||
85 | hw_write(ci, OP_USBINTR, BIT(n), BIT(n)); | ||
86 | hw_write(ci, OP_USBSTS, BIT(n), BIT(n)); | ||
87 | hw_write(ci, CAP_TESTMODE, TESTMODE_FORCE, 0); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * show_device: prints information about device capabilities and status | ||
93 | * | ||
94 | * Check "device.h" for details | ||
95 | */ | ||
96 | static ssize_t show_device(struct device *dev, struct device_attribute *attr, | ||
97 | char *buf) | ||
98 | { | ||
99 | struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); | ||
100 | struct usb_gadget *gadget = &ci->gadget; | ||
101 | int n = 0; | ||
102 | |||
103 | if (attr == NULL || buf == NULL) { | ||
104 | dev_err(ci->dev, "[%s] EINVAL\n", __func__); | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n", | ||
109 | gadget->speed); | ||
110 | n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n", | ||
111 | gadget->max_speed); | ||
112 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n", | ||
113 | gadget->is_otg); | ||
114 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n", | ||
115 | gadget->is_a_peripheral); | ||
116 | n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n", | ||
117 | gadget->b_hnp_enable); | ||
118 | n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n", | ||
119 | gadget->a_hnp_support); | ||
120 | n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n", | ||
121 | gadget->a_alt_hnp_support); | ||
122 | n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n", | ||
123 | (gadget->name ? gadget->name : "")); | ||
124 | |||
125 | return n; | ||
126 | } | ||
127 | static DEVICE_ATTR(device, S_IRUSR, show_device, NULL); | ||
128 | |||
129 | /** | ||
130 | * show_driver: prints information about attached gadget (if any) | ||
131 | * | ||
132 | * Check "device.h" for details | ||
133 | */ | ||
134 | static ssize_t show_driver(struct device *dev, struct device_attribute *attr, | ||
135 | char *buf) | ||
136 | { | ||
137 | struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); | ||
138 | struct usb_gadget_driver *driver = ci->driver; | ||
139 | int n = 0; | ||
140 | |||
141 | if (attr == NULL || buf == NULL) { | ||
142 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | if (driver == NULL) | ||
147 | return scnprintf(buf, PAGE_SIZE, | ||
148 | "There is no gadget attached!\n"); | ||
149 | |||
150 | n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n", | ||
151 | (driver->function ? driver->function : "")); | ||
152 | n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n", | ||
153 | driver->max_speed); | ||
154 | |||
155 | return n; | ||
156 | } | ||
157 | static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL); | ||
158 | 55 | ||
159 | /** | 56 | /** |
160 | * show_port_test: reads port test mode | 57 | * ci_port_test_show: reads port test mode |
161 | * | ||
162 | * Check "device.h" for details | ||
163 | */ | 58 | */ |
164 | static ssize_t show_port_test(struct device *dev, | 59 | static int ci_port_test_show(struct seq_file *s, void *data) |
165 | struct device_attribute *attr, char *buf) | ||
166 | { | 60 | { |
167 | struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); | 61 | struct ci13xxx *ci = s->private; |
168 | unsigned long flags; | 62 | unsigned long flags; |
169 | unsigned mode; | 63 | unsigned mode; |
170 | 64 | ||
171 | if (attr == NULL || buf == NULL) { | ||
172 | dev_err(ci->dev, "EINVAL\n"); | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | spin_lock_irqsave(&ci->lock, flags); | 65 | spin_lock_irqsave(&ci->lock, flags); |
177 | mode = hw_port_test_get(ci); | 66 | mode = hw_port_test_get(ci); |
178 | spin_unlock_irqrestore(&ci->lock, flags); | 67 | spin_unlock_irqrestore(&ci->lock, flags); |
179 | 68 | ||
180 | return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode); | 69 | seq_printf(s, "mode = %u\n", mode); |
70 | |||
71 | return 0; | ||
181 | } | 72 | } |
182 | 73 | ||
183 | /** | 74 | /** |
184 | * store_port_test: writes port test mode | 75 | * ci_port_test_write: writes port test mode |
185 | * | ||
186 | * Check "device.h" for details | ||
187 | */ | 76 | */ |
188 | static ssize_t store_port_test(struct device *dev, | 77 | static ssize_t ci_port_test_write(struct file *file, const char __user *ubuf, |
189 | struct device_attribute *attr, | 78 | size_t count, loff_t *ppos) |
190 | const char *buf, size_t count) | ||
191 | { | 79 | { |
192 | struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); | 80 | struct seq_file *s = file->private_data; |
81 | struct ci13xxx *ci = s->private; | ||
193 | unsigned long flags; | 82 | unsigned long flags; |
194 | unsigned mode; | 83 | unsigned mode; |
84 | char buf[32]; | ||
85 | int ret; | ||
195 | 86 | ||
196 | if (attr == NULL || buf == NULL) { | 87 | if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
197 | dev_err(ci->dev, "[%s] EINVAL\n", __func__); | 88 | return -EFAULT; |
198 | goto done; | ||
199 | } | ||
200 | 89 | ||
201 | if (sscanf(buf, "%u", &mode) != 1) { | 90 | if (sscanf(buf, "%u", &mode) != 1) |
202 | dev_err(ci->dev, "<mode>: set port test mode"); | 91 | return -EINVAL; |
203 | goto done; | ||
204 | } | ||
205 | 92 | ||
206 | spin_lock_irqsave(&ci->lock, flags); | 93 | spin_lock_irqsave(&ci->lock, flags); |
207 | if (hw_port_test_set(ci, mode)) | 94 | ret = hw_port_test_set(ci, mode); |
208 | dev_err(ci->dev, "invalid mode\n"); | ||
209 | spin_unlock_irqrestore(&ci->lock, flags); | 95 | spin_unlock_irqrestore(&ci->lock, flags); |
210 | 96 | ||
211 | done: | 97 | return ret ? ret : count; |
212 | return count; | ||
213 | } | 98 | } |
214 | static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR, | 99 | |
215 | show_port_test, store_port_test); | 100 | static int ci_port_test_open(struct inode *inode, struct file *file) |
101 | { | ||
102 | return single_open(file, ci_port_test_show, inode->i_private); | ||
103 | } | ||
104 | |||
105 | static const struct file_operations ci_port_test_fops = { | ||
106 | .open = ci_port_test_open, | ||
107 | .write = ci_port_test_write, | ||
108 | .read = seq_read, | ||
109 | .llseek = seq_lseek, | ||
110 | .release = single_release, | ||
111 | }; | ||
216 | 112 | ||
217 | /** | 113 | /** |
218 | * show_qheads: DMA contents of all queue heads | 114 | * ci_qheads_show: DMA contents of all queue heads |
219 | * | ||
220 | * Check "device.h" for details | ||
221 | */ | 115 | */ |
222 | static ssize_t show_qheads(struct device *dev, struct device_attribute *attr, | 116 | static int ci_qheads_show(struct seq_file *s, void *data) |
223 | char *buf) | ||
224 | { | 117 | { |
225 | struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); | 118 | struct ci13xxx *ci = s->private; |
226 | unsigned long flags; | 119 | unsigned long flags; |
227 | unsigned i, j, n = 0; | 120 | unsigned i, j; |
228 | 121 | ||
229 | if (attr == NULL || buf == NULL) { | 122 | if (ci->role != CI_ROLE_GADGET) { |
230 | dev_err(ci->dev, "[%s] EINVAL\n", __func__); | 123 | seq_printf(s, "not in gadget mode\n"); |
231 | return 0; | 124 | return 0; |
232 | } | 125 | } |
233 | 126 | ||
@@ -236,197 +129,119 @@ static ssize_t show_qheads(struct device *dev, struct device_attribute *attr, | |||
236 | struct ci13xxx_ep *mEpRx = &ci->ci13xxx_ep[i]; | 129 | struct ci13xxx_ep *mEpRx = &ci->ci13xxx_ep[i]; |
237 | struct ci13xxx_ep *mEpTx = | 130 | struct ci13xxx_ep *mEpTx = |
238 | &ci->ci13xxx_ep[i + ci->hw_ep_max/2]; | 131 | &ci->ci13xxx_ep[i + ci->hw_ep_max/2]; |
239 | n += scnprintf(buf + n, PAGE_SIZE - n, | 132 | seq_printf(s, "EP=%02i: RX=%08X TX=%08X\n", |
240 | "EP=%02i: RX=%08X TX=%08X\n", | 133 | i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma); |
241 | i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma); | 134 | for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) |
242 | for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) { | 135 | seq_printf(s, " %04X: %08X %08X\n", j, |
243 | n += scnprintf(buf + n, PAGE_SIZE - n, | 136 | *((u32 *)mEpRx->qh.ptr + j), |
244 | " %04X: %08X %08X\n", j, | 137 | *((u32 *)mEpTx->qh.ptr + j)); |
245 | *((u32 *)mEpRx->qh.ptr + j), | ||
246 | *((u32 *)mEpTx->qh.ptr + j)); | ||
247 | } | ||
248 | } | 138 | } |
249 | spin_unlock_irqrestore(&ci->lock, flags); | 139 | spin_unlock_irqrestore(&ci->lock, flags); |
250 | 140 | ||
251 | return n; | 141 | return 0; |
252 | } | 142 | } |
253 | static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL); | ||
254 | 143 | ||
255 | /** | 144 | static int ci_qheads_open(struct inode *inode, struct file *file) |
256 | * show_registers: dumps all registers | ||
257 | * | ||
258 | * Check "device.h" for details | ||
259 | */ | ||
260 | #define DUMP_ENTRIES 512 | ||
261 | static ssize_t show_registers(struct device *dev, | ||
262 | struct device_attribute *attr, char *buf) | ||
263 | { | 145 | { |
264 | struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); | 146 | return single_open(file, ci_qheads_show, inode->i_private); |
265 | unsigned long flags; | ||
266 | u32 *dump; | ||
267 | unsigned i, k, n = 0; | ||
268 | |||
269 | if (attr == NULL || buf == NULL) { | ||
270 | dev_err(ci->dev, "[%s] EINVAL\n", __func__); | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL); | ||
275 | if (!dump) { | ||
276 | dev_err(ci->dev, "%s: out of memory\n", __func__); | ||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | spin_lock_irqsave(&ci->lock, flags); | ||
281 | k = hw_register_read(ci, dump, DUMP_ENTRIES); | ||
282 | spin_unlock_irqrestore(&ci->lock, flags); | ||
283 | |||
284 | for (i = 0; i < k; i++) { | ||
285 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
286 | "reg[0x%04X] = 0x%08X\n", | ||
287 | i * (unsigned)sizeof(u32), dump[i]); | ||
288 | } | ||
289 | kfree(dump); | ||
290 | |||
291 | return n; | ||
292 | } | 147 | } |
293 | 148 | ||
294 | /** | 149 | static const struct file_operations ci_qheads_fops = { |
295 | * store_registers: writes value to register address | 150 | .open = ci_qheads_open, |
296 | * | 151 | .read = seq_read, |
297 | * Check "device.h" for details | 152 | .llseek = seq_lseek, |
298 | */ | 153 | .release = single_release, |
299 | static ssize_t store_registers(struct device *dev, | 154 | }; |
300 | struct device_attribute *attr, | ||
301 | const char *buf, size_t count) | ||
302 | { | ||
303 | struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); | ||
304 | unsigned long addr, data, flags; | ||
305 | |||
306 | if (attr == NULL || buf == NULL) { | ||
307 | dev_err(ci->dev, "[%s] EINVAL\n", __func__); | ||
308 | goto done; | ||
309 | } | ||
310 | |||
311 | if (sscanf(buf, "%li %li", &addr, &data) != 2) { | ||
312 | dev_err(ci->dev, | ||
313 | "<addr> <data>: write data to register address\n"); | ||
314 | goto done; | ||
315 | } | ||
316 | |||
317 | spin_lock_irqsave(&ci->lock, flags); | ||
318 | if (hw_register_write(ci, addr, data)) | ||
319 | dev_err(ci->dev, "invalid address range\n"); | ||
320 | spin_unlock_irqrestore(&ci->lock, flags); | ||
321 | |||
322 | done: | ||
323 | return count; | ||
324 | } | ||
325 | static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR, | ||
326 | show_registers, store_registers); | ||
327 | 155 | ||
328 | /** | 156 | /** |
329 | * show_requests: DMA contents of all requests currently queued (all endpts) | 157 | * ci_requests_show: DMA contents of all requests currently queued (all endpts) |
330 | * | ||
331 | * Check "device.h" for details | ||
332 | */ | 158 | */ |
333 | static ssize_t show_requests(struct device *dev, struct device_attribute *attr, | 159 | static int ci_requests_show(struct seq_file *s, void *data) |
334 | char *buf) | ||
335 | { | 160 | { |
336 | struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); | 161 | struct ci13xxx *ci = s->private; |
337 | unsigned long flags; | 162 | unsigned long flags; |
338 | struct list_head *ptr = NULL; | 163 | struct list_head *ptr = NULL; |
339 | struct ci13xxx_req *req = NULL; | 164 | struct ci13xxx_req *req = NULL; |
340 | unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32); | 165 | unsigned i, j, qsize = sizeof(struct ci13xxx_td)/sizeof(u32); |
341 | 166 | ||
342 | if (attr == NULL || buf == NULL) { | 167 | if (ci->role != CI_ROLE_GADGET) { |
343 | dev_err(ci->dev, "[%s] EINVAL\n", __func__); | 168 | seq_printf(s, "not in gadget mode\n"); |
344 | return 0; | 169 | return 0; |
345 | } | 170 | } |
346 | 171 | ||
347 | spin_lock_irqsave(&ci->lock, flags); | 172 | spin_lock_irqsave(&ci->lock, flags); |
348 | for (i = 0; i < ci->hw_ep_max; i++) | 173 | for (i = 0; i < ci->hw_ep_max; i++) |
349 | list_for_each(ptr, &ci->ci13xxx_ep[i].qh.queue) | 174 | list_for_each(ptr, &ci->ci13xxx_ep[i].qh.queue) { |
350 | { | ||
351 | req = list_entry(ptr, struct ci13xxx_req, queue); | 175 | req = list_entry(ptr, struct ci13xxx_req, queue); |
352 | 176 | ||
353 | n += scnprintf(buf + n, PAGE_SIZE - n, | 177 | seq_printf(s, "EP=%02i: TD=%08X %s\n", |
354 | "EP=%02i: TD=%08X %s\n", | 178 | i % ci->hw_ep_max/2, (u32)req->dma, |
355 | i % ci->hw_ep_max/2, (u32)req->dma, | 179 | ((i < ci->hw_ep_max/2) ? "RX" : "TX")); |
356 | ((i < ci->hw_ep_max/2) ? "RX" : "TX")); | ||
357 | 180 | ||
358 | for (j = 0; j < qSize; j++) | 181 | for (j = 0; j < qsize; j++) |
359 | n += scnprintf(buf + n, PAGE_SIZE - n, | 182 | seq_printf(s, " %04X: %08X\n", j, |
360 | " %04X: %08X\n", j, | 183 | *((u32 *)req->ptr + j)); |
361 | *((u32 *)req->ptr + j)); | ||
362 | } | 184 | } |
363 | spin_unlock_irqrestore(&ci->lock, flags); | 185 | spin_unlock_irqrestore(&ci->lock, flags); |
364 | 186 | ||
365 | return n; | 187 | return 0; |
188 | } | ||
189 | |||
190 | static int ci_requests_open(struct inode *inode, struct file *file) | ||
191 | { | ||
192 | return single_open(file, ci_requests_show, inode->i_private); | ||
366 | } | 193 | } |
367 | static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL); | 194 | |
195 | static const struct file_operations ci_requests_fops = { | ||
196 | .open = ci_requests_open, | ||
197 | .read = seq_read, | ||
198 | .llseek = seq_lseek, | ||
199 | .release = single_release, | ||
200 | }; | ||
368 | 201 | ||
369 | /** | 202 | /** |
370 | * dbg_create_files: initializes the attribute interface | 203 | * dbg_create_files: initializes the attribute interface |
371 | * @dev: device | 204 | * @ci: device |
372 | * | 205 | * |
373 | * This function returns an error code | 206 | * This function returns an error code |
374 | */ | 207 | */ |
375 | int dbg_create_files(struct device *dev) | 208 | int dbg_create_files(struct ci13xxx *ci) |
376 | { | 209 | { |
377 | int retval = 0; | 210 | struct dentry *dent; |
378 | 211 | ||
379 | if (dev == NULL) | 212 | ci->debugfs = debugfs_create_dir(dev_name(ci->dev), NULL); |
380 | return -EINVAL; | 213 | if (!ci->debugfs) |
381 | retval = device_create_file(dev, &dev_attr_device); | 214 | return -ENOMEM; |
382 | if (retval) | 215 | |
383 | goto done; | 216 | dent = debugfs_create_file("device", S_IRUGO, ci->debugfs, ci, |
384 | retval = device_create_file(dev, &dev_attr_driver); | 217 | &ci_device_fops); |
385 | if (retval) | 218 | if (!dent) |
386 | goto rm_device; | 219 | goto err; |
387 | retval = device_create_file(dev, &dev_attr_port_test); | 220 | |
388 | if (retval) | 221 | dent = debugfs_create_file("port_test", S_IRUGO | S_IWUSR, ci->debugfs, |
389 | goto rm_driver; | 222 | ci, &ci_port_test_fops); |
390 | retval = device_create_file(dev, &dev_attr_qheads); | 223 | if (!dent) |
391 | if (retval) | 224 | goto err; |
392 | goto rm_port_test; | 225 | |
393 | retval = device_create_file(dev, &dev_attr_registers); | 226 | dent = debugfs_create_file("qheads", S_IRUGO, ci->debugfs, ci, |
394 | if (retval) | 227 | &ci_qheads_fops); |
395 | goto rm_qheads; | 228 | if (!dent) |
396 | retval = device_create_file(dev, &dev_attr_requests); | 229 | goto err; |
397 | if (retval) | 230 | |
398 | goto rm_registers; | 231 | dent = debugfs_create_file("requests", S_IRUGO, ci->debugfs, ci, |
399 | return 0; | 232 | &ci_requests_fops); |
400 | 233 | if (dent) | |
401 | rm_registers: | 234 | return 0; |
402 | device_remove_file(dev, &dev_attr_registers); | 235 | err: |
403 | rm_qheads: | 236 | debugfs_remove_recursive(ci->debugfs); |
404 | device_remove_file(dev, &dev_attr_qheads); | 237 | return -ENOMEM; |
405 | rm_port_test: | ||
406 | device_remove_file(dev, &dev_attr_port_test); | ||
407 | rm_driver: | ||
408 | device_remove_file(dev, &dev_attr_driver); | ||
409 | rm_device: | ||
410 | device_remove_file(dev, &dev_attr_device); | ||
411 | done: | ||
412 | return retval; | ||
413 | } | 238 | } |
414 | 239 | ||
415 | /** | 240 | /** |
416 | * dbg_remove_files: destroys the attribute interface | 241 | * dbg_remove_files: destroys the attribute interface |
417 | * @dev: device | 242 | * @ci: device |
418 | * | ||
419 | * This function returns an error code | ||
420 | */ | 243 | */ |
421 | int dbg_remove_files(struct device *dev) | 244 | void dbg_remove_files(struct ci13xxx *ci) |
422 | { | 245 | { |
423 | if (dev == NULL) | 246 | debugfs_remove_recursive(ci->debugfs); |
424 | return -EINVAL; | ||
425 | device_remove_file(dev, &dev_attr_requests); | ||
426 | device_remove_file(dev, &dev_attr_registers); | ||
427 | device_remove_file(dev, &dev_attr_qheads); | ||
428 | device_remove_file(dev, &dev_attr_port_test); | ||
429 | device_remove_file(dev, &dev_attr_driver); | ||
430 | device_remove_file(dev, &dev_attr_device); | ||
431 | return 0; | ||
432 | } | 247 | } |
diff --git a/drivers/usb/chipidea/debug.h b/drivers/usb/chipidea/debug.h index 425f1ff6284a..7ca6ca0a24a5 100644 --- a/drivers/usb/chipidea/debug.h +++ b/drivers/usb/chipidea/debug.h | |||
@@ -14,17 +14,16 @@ | |||
14 | #define __DRIVERS_USB_CHIPIDEA_DEBUG_H | 14 | #define __DRIVERS_USB_CHIPIDEA_DEBUG_H |
15 | 15 | ||
16 | #ifdef CONFIG_USB_CHIPIDEA_DEBUG | 16 | #ifdef CONFIG_USB_CHIPIDEA_DEBUG |
17 | int dbg_create_files(struct device *dev); | 17 | int dbg_create_files(struct ci13xxx *ci); |
18 | int dbg_remove_files(struct device *dev); | 18 | void dbg_remove_files(struct ci13xxx *ci); |
19 | #else | 19 | #else |
20 | static inline int dbg_create_files(struct device *dev) | 20 | static inline int dbg_create_files(struct ci13xxx *ci) |
21 | { | 21 | { |
22 | return 0; | 22 | return 0; |
23 | } | 23 | } |
24 | 24 | ||
25 | static inline int dbg_remove_files(struct device *dev) | 25 | static inline void dbg_remove_files(struct ci13xxx *ci) |
26 | { | 26 | { |
27 | return 0; | ||
28 | } | 27 | } |
29 | #endif | 28 | #endif |
30 | 29 | ||
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index ed498cb7fbfa..d945391e3c6c 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -1697,7 +1697,7 @@ static int udc_start(struct ci13xxx *ci) | |||
1697 | goto put_transceiver; | 1697 | goto put_transceiver; |
1698 | } | 1698 | } |
1699 | 1699 | ||
1700 | retval = dbg_create_files(ci->dev); | 1700 | retval = dbg_create_files(ci); |
1701 | if (retval) | 1701 | if (retval) |
1702 | goto unreg_device; | 1702 | goto unreg_device; |
1703 | 1703 | ||
@@ -1726,7 +1726,7 @@ remove_trans: | |||
1726 | 1726 | ||
1727 | dev_err(dev, "error = %i\n", retval); | 1727 | dev_err(dev, "error = %i\n", retval); |
1728 | remove_dbg: | 1728 | remove_dbg: |
1729 | dbg_remove_files(ci->dev); | 1729 | dbg_remove_files(ci); |
1730 | unreg_device: | 1730 | unreg_device: |
1731 | device_unregister(&ci->gadget.dev); | 1731 | device_unregister(&ci->gadget.dev); |
1732 | put_transceiver: | 1732 | put_transceiver: |
@@ -1763,7 +1763,7 @@ static void udc_stop(struct ci13xxx *ci) | |||
1763 | if (ci->global_phy) | 1763 | if (ci->global_phy) |
1764 | usb_put_phy(ci->transceiver); | 1764 | usb_put_phy(ci->transceiver); |
1765 | } | 1765 | } |
1766 | dbg_remove_files(ci->dev); | 1766 | dbg_remove_files(ci); |
1767 | device_unregister(&ci->gadget.dev); | 1767 | device_unregister(&ci->gadget.dev); |
1768 | /* my kobject is dynamic, I swear! */ | 1768 | /* my kobject is dynamic, I swear! */ |
1769 | memset(&ci->gadget, 0, sizeof(ci->gadget)); | 1769 | memset(&ci->gadget, 0, sizeof(ci->gadget)); |