]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/usb/musb/musb_procfs.c
Merge 2.6.23
[linux-2.6-omap-h63xx.git] / drivers / usb / musb / musb_procfs.c
1 /*
2  * MUSB OTG driver debug support
3  *
4  * Copyright 2005 Mentor Graphics Corporation
5  * Copyright (C) 2005-2006 by Texas Instruments
6  * Copyright (C) 2006-2007 Nokia Corporation
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
25  * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34
35 #include <linux/kernel.h>
36 #include <linux/proc_fs.h>
37 #include <linux/seq_file.h>
38 #include <asm/uaccess.h>        /* FIXME remove procfs writes */
39 #include <asm/arch/hardware.h>
40
41 #include "musb_core.h"
42
43 #include "davinci.h"
44
45
46 const char *otg_state_string(struct musb *musb)
47 {
48         switch (musb->xceiv.state) {
49         case OTG_STATE_A_IDLE:          return "a_idle";
50         case OTG_STATE_A_WAIT_VRISE:    return "a_wait_vrise";
51         case OTG_STATE_A_WAIT_BCON:     return "a_wait_bcon";
52         case OTG_STATE_A_HOST:          return "a_host";
53         case OTG_STATE_A_SUSPEND:       return "a_suspend";
54         case OTG_STATE_A_PERIPHERAL:    return "a_peripheral";
55         case OTG_STATE_A_WAIT_VFALL:    return "a_wait_vfall";
56         case OTG_STATE_A_VBUS_ERR:      return "a_vbus_err";
57         case OTG_STATE_B_IDLE:          return "b_idle";
58         case OTG_STATE_B_SRP_INIT:      return "b_srp_init";
59         case OTG_STATE_B_PERIPHERAL:    return "b_peripheral";
60         case OTG_STATE_B_WAIT_ACON:     return "b_wait_acon";
61         case OTG_STATE_B_HOST:          return "b_host";
62         default:                        return "UNDEFINED";
63         }
64 }
65
66 #ifdef CONFIG_USB_MUSB_HDRC_HCD
67
68 static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
69 {
70         int                             count;
71         int                             tmp;
72         struct usb_host_endpoint        *hep = qh->hep;
73         struct urb                      *urb;
74
75         count = snprintf(buf, max, "    qh %p dev%d ep%d%s max%d\n",
76                         qh, qh->dev->devnum, qh->epnum,
77                         ({ char *s; switch (qh->type) {
78                         case USB_ENDPOINT_XFER_BULK:
79                                 s = "-bulk"; break;
80                         case USB_ENDPOINT_XFER_INT:
81                                 s = "-int"; break;
82                         case USB_ENDPOINT_XFER_CONTROL:
83                                 s = ""; break;
84                         default:
85                                 s = "iso"; break;
86                         }; s; }),
87                         qh->maxpacket);
88         if (count <= 0)
89                 return 0;
90         buf += count;
91         max -= count;
92
93         list_for_each_entry(urb, &hep->urb_list, urb_list) {
94                 tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n",
95                                 usb_pipein(urb->pipe) ? "in" : "out",
96                                 urb, urb->actual_length,
97                                 urb->transfer_buffer_length);
98                 if (tmp <= 0)
99                         break;
100                 tmp = min(tmp, (int)max);
101                 count += tmp;
102                 buf += tmp;
103                 max -= tmp;
104         }
105         return count;
106 }
107
108 static int
109 dump_queue(struct list_head *q, char *buf, unsigned max)
110 {
111         int             count = 0;
112         struct musb_qh  *qh;
113
114         list_for_each_entry(qh, q, ring) {
115                 int     tmp;
116
117                 tmp = dump_qh(qh, buf, max);
118                 if (tmp <= 0)
119                         break;
120                 tmp = min(tmp, (int)max);
121                 count += tmp;
122                 buf += tmp;
123                 max -= tmp;
124         }
125         return count;
126 }
127
128 #endif  /* HCD */
129
130 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
131 static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max)
132 {
133         char            *buf = buffer;
134         int             code = 0;
135         void __iomem    *regs = ep->hw_ep->regs;
136         char            *mode = "1buf";
137
138         if (ep->is_in) {
139                 if (ep->hw_ep->tx_double_buffered)
140                         mode = "2buf";
141         } else {
142                 if (ep->hw_ep->rx_double_buffered)
143                         mode = "2buf";
144         }
145
146         do {
147                 struct usb_request      *req;
148
149                 code = snprintf(buf, max,
150                                 "\n%s (hw%d): %s%s, csr %04x maxp %04x\n",
151                                 ep->name, ep->current_epnum,
152                                 mode, ep->dma ? " dma" : "",
153                                 musb_readw(regs,
154                                         (ep->is_in || !ep->current_epnum)
155                                                 ? MUSB_TXCSR
156                                                 : MUSB_RXCSR),
157                                 musb_readw(regs, ep->is_in
158                                                 ? MUSB_TXMAXP
159                                                 : MUSB_RXMAXP)
160                                 );
161                 if (code <= 0)
162                         break;
163                 code = min(code, (int) max);
164                 buf += code;
165                 max -= code;
166
167                 if (is_cppi_enabled() && ep->current_epnum) {
168                         unsigned        cppi = ep->current_epnum - 1;
169                         void __iomem    *base = ep->musb->ctrl_base;
170                         unsigned        off1 = cppi << 2;
171                         void __iomem    *ram = base;
172                         char            tmp[16];
173
174                         if (ep->is_in) {
175                                 ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi);
176                                 tmp[0] = 0;
177                         } else {
178                                 ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi);
179                                 snprintf(tmp, sizeof tmp, "%d left, ",
180                                         musb_readl(base,
181                                         DAVINCI_RXCPPI_BUFCNT0_REG + off1));
182                         }
183
184                         code = snprintf(buf, max, "%cX DMA%d: %s"
185                                         "%08x %08x, %08x %08x; "
186                                         "%08x %08x %08x .. %08x\n",
187                                 ep->is_in ? 'T' : 'R',
188                                 ep->current_epnum - 1, tmp,
189                                 musb_readl(ram, 0 * 4),
190                                 musb_readl(ram, 1 * 4),
191                                 musb_readl(ram, 2 * 4),
192                                 musb_readl(ram, 3 * 4),
193                                 musb_readl(ram, 4 * 4),
194                                 musb_readl(ram, 5 * 4),
195                                 musb_readl(ram, 6 * 4),
196                                 musb_readl(ram, 7 * 4));
197                         if (code <= 0)
198                                 break;
199                         code = min(code, (int) max);
200                         buf += code;
201                         max -= code;
202                 }
203
204                 if (list_empty(&ep->req_list)) {
205                         code = snprintf(buf, max, "\t(queue empty)\n");
206                         if (code <= 0)
207                                 break;
208                         code = min(code, (int) max);
209                         buf += code;
210                         max -= code;
211                         break;
212                 }
213                 list_for_each_entry (req, &ep->req_list, list) {
214                         code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n",
215                                         req,
216                                         req->zero ? "zero, " : "",
217                                         req->short_not_ok ? "!short, " : "",
218                                         req->actual, req->length);
219                         if (code <= 0)
220                                 break;
221                         code = min(code, (int) max);
222                         buf += code;
223                         max -= code;
224                 }
225         } while(0);
226         return buf - buffer;
227 }
228 #endif
229
230 static int
231 dump_end_info(struct musb *musb, u8 epnum, char *aBuffer, unsigned max)
232 {
233         int                     code = 0;
234         char                    *buf = aBuffer;
235         struct musb_hw_ep       *hw_ep = &musb->endpoints[epnum];
236
237         do {
238                 musb_ep_select(musb->mregs, epnum);
239 #ifdef CONFIG_USB_MUSB_HDRC_HCD
240                 if (is_host_active(musb)) {
241                         int             dump_rx, dump_tx;
242                         void __iomem    *regs = hw_ep->regs;
243
244                         /* TEMPORARY (!) until we have a real periodic
245                          * schedule tree ...
246                          */
247                         if (!epnum) {
248                                 /* control is shared, uses RX queue
249                                  * but (mostly) shadowed tx registers
250                                  */
251                                 dump_tx = !list_empty(&musb->control);
252                                 dump_rx = 0;
253                         } else if (hw_ep == musb->bulk_ep) {
254                                 dump_tx = !list_empty(&musb->out_bulk);
255                                 dump_rx = !list_empty(&musb->in_bulk);
256                         } else if (musb->periodic[epnum]) {
257                                 struct usb_host_endpoint        *hep;
258
259                                 hep = musb->periodic[epnum]->hep;
260                                 dump_rx = hep->desc.bEndpointAddress
261                                                 & USB_ENDPOINT_DIR_MASK;
262                                 dump_tx = !dump_rx;
263                         } else
264                                 break;
265                         /* END TEMPORARY */
266
267
268                         if (dump_rx) {
269                                 code = snprintf(buf, max,
270                                         "\nRX%d: %s rxcsr %04x interval %02x "
271                                         "max %04x type %02x; "
272                                         "dev %d hub %d port %d"
273                                         "\n",
274                                         epnum,
275                                         hw_ep->rx_double_buffered
276                                                 ? "2buf" : "1buf",
277                                         musb_readw(regs, MUSB_RXCSR),
278                                         musb_readb(regs, MUSB_RXINTERVAL),
279                                         musb_readw(regs, MUSB_RXMAXP),
280                                         musb_readb(regs, MUSB_RXTYPE),
281                                         /* FIXME:  assumes multipoint */
282                                         musb_readb(musb->mregs,
283                                                 MUSB_BUSCTL_OFFSET(epnum,
284                                                 MUSB_RXFUNCADDR)),
285                                         musb_readb(musb->mregs,
286                                                 MUSB_BUSCTL_OFFSET(epnum,
287                                                 MUSB_RXHUBADDR)),
288                                         musb_readb(musb->mregs,
289                                                 MUSB_BUSCTL_OFFSET(epnum,
290                                                 MUSB_RXHUBPORT))
291                                         );
292                                 if (code <= 0)
293                                         break;
294                                 code = min(code, (int) max);
295                                 buf += code;
296                                 max -= code;
297
298                                 if (is_cppi_enabled()
299                                                 && epnum
300                                                 && hw_ep->rx_channel) {
301                                         unsigned        cppi = epnum - 1;
302                                         unsigned        off1 = cppi << 2;
303                                         void __iomem    *base;
304                                         void __iomem    *ram;
305                                         char            tmp[16];
306
307                                         base = musb->ctrl_base;
308                                         ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
309                                                         cppi) + base;
310                                         snprintf(tmp, sizeof tmp, "%d left, ",
311                                                 musb_readl(base,
312                                                 DAVINCI_RXCPPI_BUFCNT0_REG
313                                                                 + off1));
314
315                                         code = snprintf(buf, max,
316                                                 "    rx dma%d: %s"
317                                                 "%08x %08x, %08x %08x; "
318                                                 "%08x %08x %08x .. %08x\n",
319                                                 cppi, tmp,
320                                                 musb_readl(ram, 0 * 4),
321                                                 musb_readl(ram, 1 * 4),
322                                                 musb_readl(ram, 2 * 4),
323                                                 musb_readl(ram, 3 * 4),
324                                                 musb_readl(ram, 4 * 4),
325                                                 musb_readl(ram, 5 * 4),
326                                                 musb_readl(ram, 6 * 4),
327                                                 musb_readl(ram, 7 * 4));
328                                         if (code <= 0)
329                                                 break;
330                                         code = min(code, (int) max);
331                                         buf += code;
332                                         max -= code;
333                                 }
334
335                                 if (hw_ep == musb->bulk_ep
336                                                 && !list_empty(
337                                                         &musb->in_bulk)) {
338                                         code = dump_queue(&musb->in_bulk,
339                                                         buf, max);
340                                         if (code <= 0)
341                                                 break;
342                                         code = min(code, (int) max);
343                                         buf += code;
344                                         max -= code;
345                                 } else if (musb->periodic[epnum]) {
346                                         code = dump_qh(musb->periodic[epnum],
347                                                         buf, max);
348                                         if (code <= 0)
349                                                 break;
350                                         code = min(code, (int) max);
351                                         buf += code;
352                                         max -= code;
353                                 }
354                         }
355
356                         if (dump_tx) {
357                                 code = snprintf(buf, max,
358                                         "\nTX%d: %s txcsr %04x interval %02x "
359                                         "max %04x type %02x; "
360                                         "dev %d hub %d port %d"
361                                         "\n",
362                                         epnum,
363                                         hw_ep->tx_double_buffered
364                                                 ? "2buf" : "1buf",
365                                         musb_readw(regs, MUSB_TXCSR),
366                                         musb_readb(regs, MUSB_TXINTERVAL),
367                                         musb_readw(regs, MUSB_TXMAXP),
368                                         musb_readb(regs, MUSB_TXTYPE),
369                                         /* FIXME:  assumes multipoint */
370                                         musb_readb(musb->mregs,
371                                                 MUSB_BUSCTL_OFFSET(epnum,
372                                                 MUSB_TXFUNCADDR)),
373                                         musb_readb(musb->mregs,
374                                                 MUSB_BUSCTL_OFFSET(epnum,
375                                                 MUSB_TXHUBADDR)),
376                                         musb_readb(musb->mregs,
377                                                 MUSB_BUSCTL_OFFSET(epnum,
378                                                 MUSB_TXHUBPORT))
379                                         );
380                                 if (code <= 0)
381                                         break;
382                                 code = min(code, (int) max);
383                                 buf += code;
384                                 max -= code;
385
386                                 if (is_cppi_enabled()
387                                                 && epnum
388                                                 && hw_ep->tx_channel) {
389                                         unsigned        cppi = epnum - 1;
390                                         void __iomem    *base;
391                                         void __iomem    *ram;
392
393                                         base = musb->ctrl_base;
394                                         ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
395                                                         cppi) + base;
396                                         code = snprintf(buf, max,
397                                                 "    tx dma%d: "
398                                                 "%08x %08x, %08x %08x; "
399                                                 "%08x %08x %08x .. %08x\n",
400                                                 cppi,
401                                                 musb_readl(ram, 0 * 4),
402                                                 musb_readl(ram, 1 * 4),
403                                                 musb_readl(ram, 2 * 4),
404                                                 musb_readl(ram, 3 * 4),
405                                                 musb_readl(ram, 4 * 4),
406                                                 musb_readl(ram, 5 * 4),
407                                                 musb_readl(ram, 6 * 4),
408                                                 musb_readl(ram, 7 * 4));
409                                         if (code <= 0)
410                                                 break;
411                                         code = min(code, (int) max);
412                                         buf += code;
413                                         max -= code;
414                                 }
415
416                                 if (hw_ep == musb->control_ep
417                                                 && !list_empty(
418                                                         &musb->control)) {
419                                         code = dump_queue(&musb->control,
420                                                         buf, max);
421                                         if (code <= 0)
422                                                 break;
423                                         code = min(code, (int) max);
424                                         buf += code;
425                                         max -= code;
426                                 } else if (hw_ep == musb->bulk_ep
427                                                 && !list_empty(
428                                                         &musb->out_bulk)) {
429                                         code = dump_queue(&musb->out_bulk,
430                                                         buf, max);
431                                         if (code <= 0)
432                                                 break;
433                                         code = min(code, (int) max);
434                                         buf += code;
435                                         max -= code;
436                                 } else if (musb->periodic[epnum]) {
437                                         code = dump_qh(musb->periodic[epnum],
438                                                         buf, max);
439                                         if (code <= 0)
440                                                 break;
441                                         code = min(code, (int) max);
442                                         buf += code;
443                                         max -= code;
444                                 }
445                         }
446                 }
447 #endif
448 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
449                 if (is_peripheral_active(musb)) {
450                         code = 0;
451
452                         if (hw_ep->ep_in.desc || !epnum) {
453                                 code = dump_ep(&hw_ep->ep_in, buf, max);
454                                 if (code <= 0)
455                                         break;
456                                 code = min(code, (int) max);
457                                 buf += code;
458                                 max -= code;
459                         }
460                         if (hw_ep->ep_out.desc) {
461                                 code = dump_ep(&hw_ep->ep_out, buf, max);
462                                 if (code <= 0)
463                                         break;
464                                 code = min(code, (int) max);
465                                 buf += code;
466                                 max -= code;
467                         }
468                 }
469 #endif
470         } while (0);
471
472         return buf - aBuffer;
473 }
474
475 /* Dump the current status and compile options.
476  * @param musb the device driver instance
477  * @param buffer where to dump the status; it must be big enough hold the
478  * result otherwise "BAD THINGS HAPPENS(TM)".
479  */
480 static int dump_header_stats(struct musb *musb, char *buffer)
481 {
482         int code, count = 0;
483         const void __iomem *mbase = musb->mregs;
484
485         *buffer = 0;
486         count = sprintf(buffer, "Status: %sHDRC, Mode=%s "
487                                 "(Power=%02x, DevCtl=%02x)\n",
488                         (musb->is_multipoint ? "M" : ""), MUSB_MODE(musb),
489                         musb_readb(mbase, MUSB_POWER),
490                         musb_readb(mbase, MUSB_DEVCTL));
491         if (count <= 0)
492                 return 0;
493         buffer += count;
494
495         code = sprintf(buffer, "OTG state: %s; %sactive\n",
496                         otg_state_string(musb),
497                         musb->is_active ? "" : "in");
498         if (code <= 0)
499                 goto done;
500         buffer += code;
501         count += code;
502
503         code = sprintf(buffer,
504                         "Options: "
505 #ifdef CONFIG_MUSB_PIO_ONLY
506                         "pio"
507 #elif defined(CONFIG_USB_TI_CPPI_DMA)
508                         "cppi-dma"
509 #elif defined(CONFIG_USB_INVENTRA_DMA)
510                         "musb-dma"
511 #elif defined(CONFIG_USB_TUSB_OMAP_DMA)
512                         "tusb-omap-dma"
513 #else
514                         "?dma?"
515 #endif
516                         ", "
517 #ifdef CONFIG_USB_MUSB_OTG
518                         "otg (peripheral+host)"
519 #elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
520                         "peripheral"
521 #elif defined(CONFIG_USB_MUSB_HDRC_HCD)
522                         "host"
523 #endif
524                         ", debug=%d [eps=%d]\n",
525                 debug,
526                 musb->nr_endpoints);
527         if (code <= 0)
528                 goto done;
529         count += code;
530         buffer += code;
531
532 #ifdef  CONFIG_USB_GADGET_MUSB_HDRC
533         code = sprintf(buffer, "Peripheral address: %02x\n",
534                         musb_readb(musb->ctrl_base, MUSB_FADDR));
535         if (code <= 0)
536                 goto done;
537         buffer += code;
538         count += code;
539 #endif
540
541 #ifdef  CONFIG_USB_MUSB_HDRC_HCD
542         code = sprintf(buffer, "Root port status: %08x\n",
543                         musb->port1_status);
544         if (code <= 0)
545                 goto done;
546         buffer += code;
547         count += code;
548 #endif
549
550 #ifdef  CONFIG_ARCH_DAVINCI
551         code = sprintf(buffer,
552                         "DaVinci: ctrl=%02x stat=%1x phy=%03x\n"
553                         "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x"
554                         "\n",
555                         musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG),
556                         musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG),
557                         __raw_readl((void __force __iomem *)
558                                         IO_ADDRESS(USBPHY_CTL_PADDR)),
559                         musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG),
560                         musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG),
561                         musb_readl(musb->ctrl_base,
562                                         DAVINCI_USB_INT_SOURCE_REG),
563                         musb_readl(musb->ctrl_base,
564                                         DAVINCI_USB_INT_MASK_REG));
565         if (code <= 0)
566                 goto done;
567         count += code;
568         buffer += code;
569 #endif  /* DAVINCI */
570
571 #ifdef CONFIG_USB_TUSB6010
572         code = sprintf(buffer,
573                         "TUSB6010: devconf %08x, phy enable %08x drive %08x"
574                         "\n\totg %03x timer %08x"
575                         "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x"
576                         "\n",
577                         musb_readl(musb->ctrl_base, TUSB_DEV_CONF),
578                         musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
579                         musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL),
580                         musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT),
581                         musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER),
582                         musb_readl(musb->ctrl_base, TUSB_PRCM_CONF),
583                         musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT),
584                         musb_readl(musb->ctrl_base, TUSB_INT_SRC),
585                         musb_readl(musb->ctrl_base, TUSB_INT_MASK));
586         if (code <= 0)
587                 goto done;
588         count += code;
589         buffer += code;
590 #endif  /* DAVINCI */
591
592         if (is_cppi_enabled() && musb->dma_controller) {
593                 code = sprintf(buffer,
594                                 "CPPI: txcr=%d txsrc=%01x txena=%01x; "
595                                 "rxcr=%d rxsrc=%01x rxena=%01x "
596                                 "\n",
597                                 musb_readl(musb->ctrl_base,
598                                                 DAVINCI_TXCPPI_CTRL_REG),
599                                 musb_readl(musb->ctrl_base,
600                                                 DAVINCI_TXCPPI_RAW_REG),
601                                 musb_readl(musb->ctrl_base,
602                                                 DAVINCI_TXCPPI_INTENAB_REG),
603                                 musb_readl(musb->ctrl_base,
604                                                 DAVINCI_RXCPPI_CTRL_REG),
605                                 musb_readl(musb->ctrl_base,
606                                                 DAVINCI_RXCPPI_RAW_REG),
607                                 musb_readl(musb->ctrl_base,
608                                                 DAVINCI_RXCPPI_INTENAB_REG));
609                 if (code <= 0)
610                         goto done;
611                 count += code;
612                 buffer += code;
613         }
614
615 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
616         if (is_peripheral_enabled(musb)) {
617                 code = sprintf(buffer, "Gadget driver: %s\n",
618                                 musb->gadget_driver
619                                         ? musb->gadget_driver->driver.name
620                                         : "(none)");
621                 if (code <= 0)
622                         goto done;
623                 count += code;
624                 buffer += code;
625         }
626 #endif
627
628 done:
629         return count;
630 }
631
632 /* Write to ProcFS
633  *
634  * C soft-connect
635  * c soft-disconnect
636  * I enable HS
637  * i disable HS
638  * s stop session
639  * F force session (OTG-unfriendly)
640  * E rElinquish bus (OTG)
641  * H request host mode
642  * h cancel host request
643  * T start sending TEST_PACKET
644  * D<num> set/query the debug level
645  */
646 static int musb_proc_write(struct file *file, const char __user *buffer,
647                         unsigned long count, void *data)
648 {
649         char cmd;
650         u8 reg;
651         struct musb *musb = (struct musb *)data;
652         void __iomem *mbase = musb->mregs;
653
654         /* MOD_INC_USE_COUNT; */
655
656         if (unlikely(copy_from_user(&cmd, buffer, 1)))
657                 return -EFAULT;
658
659         switch (cmd) {
660         case 'C':
661                 if (mbase) {
662                         reg = musb_readb(mbase, MUSB_POWER)
663                                         | MUSB_POWER_SOFTCONN;
664                         musb_writeb(mbase, MUSB_POWER, reg);
665                 }
666                 break;
667
668         case 'c':
669                 if (mbase) {
670                         reg = musb_readb(mbase, MUSB_POWER)
671                                         & ~MUSB_POWER_SOFTCONN;
672                         musb_writeb(mbase, MUSB_POWER, reg);
673                 }
674                 break;
675
676         case 'I':
677                 if (mbase) {
678                         reg = musb_readb(mbase, MUSB_POWER)
679                                         | MUSB_POWER_HSENAB;
680                         musb_writeb(mbase, MUSB_POWER, reg);
681                 }
682                 break;
683
684         case 'i':
685                 if (mbase) {
686                         reg = musb_readb(mbase, MUSB_POWER)
687                                         & ~MUSB_POWER_HSENAB;
688                         musb_writeb(mbase, MUSB_POWER, reg);
689                 }
690                 break;
691
692         case 'F':
693                 reg = musb_readb(mbase, MUSB_DEVCTL);
694                 reg |= MUSB_DEVCTL_SESSION;
695                 musb_writeb(mbase, MUSB_DEVCTL, reg);
696                 break;
697
698         case 'H':
699                 if (mbase) {
700                         reg = musb_readb(mbase, MUSB_DEVCTL);
701                         reg |= MUSB_DEVCTL_HR;
702                         musb_writeb(mbase, MUSB_DEVCTL, reg);
703                         /* MUSB_HST_MODE( ((struct musb*)data) ); */
704                         /* WARN("Host Mode\n"); */
705                 }
706                 break;
707
708         case 'h':
709                 if (mbase) {
710                         reg = musb_readb(mbase, MUSB_DEVCTL);
711                         reg &= ~MUSB_DEVCTL_HR;
712                         musb_writeb(mbase, MUSB_DEVCTL, reg);
713                 }
714                 break;
715
716         case 'T':
717                 if (mbase) {
718                         musb_load_testpacket(musb);
719                         musb_writeb(mbase, MUSB_TESTMODE,
720                                         MUSB_TEST_PACKET);
721                 }
722                 break;
723
724 #if (MUSB_DEBUG>0)
725                 /* set/read debug level */
726         case 'D':{
727                         if (count > 1) {
728                                 char digits[8], *p = digits;
729                                 int i = 0, level = 0, sign = 1;
730                                 int len = min(count - 1, (unsigned long)8);
731
732                                 if (copy_from_user(&digits, &buffer[1], len))
733                                         return -EFAULT;
734
735                                 /* optional sign */
736                                 if (*p == '-') {
737                                         len -= 1;
738                                         sign = -sign;
739                                         p++;
740                                 }
741
742                                 /* read it */
743                                 while (i++ < len && *p > '0' && *p < '9') {
744                                         level = level * 10 + (*p - '0');
745                                         p++;
746                                 }
747
748                                 level *= sign;
749                                 DBG(1, "debug level %d\n", level);
750                                 debug = level;
751                         }
752                 }
753                 break;
754
755
756         case '?':
757                 INFO("?: you are seeing it\n");
758                 INFO("C/c: soft connect enable/disable\n");
759                 INFO("I/i: hispeed enable/disable\n");
760                 INFO("F: force session start\n");
761                 INFO("H: host mode\n");
762                 INFO("T: start sending TEST_PACKET\n");
763                 INFO("D: set/read dbug level\n");
764                 break;
765 #endif
766
767         default:
768                 ERR("Command %c not implemented\n", cmd);
769                 break;
770         }
771
772         musb_platform_try_idle(musb, 0);
773
774         return count;
775 }
776
777 static int musb_proc_read(char *page, char **start,
778                         off_t off, int count, int *eof, void *data)
779 {
780         char *buffer = page;
781         int code = 0;
782         unsigned long   flags;
783         struct musb     *musb = data;
784         unsigned        epnum;
785
786         count -= off;
787         count -= 1;             /* for NUL at end */
788         if (count <= 0)
789                 return -EINVAL;
790
791         spin_lock_irqsave(&musb->lock, flags);
792
793         code = dump_header_stats(musb, buffer);
794         if (code > 0) {
795                 buffer += code;
796                 count -= code;
797         }
798
799         /* generate the report for the end points */
800         /* REVISIT ... not unless something's connected! */
801         for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints;
802                         epnum++) {
803                 code = dump_end_info(musb, epnum, buffer, count);
804                 if (code > 0) {
805                         buffer += code;
806                         count -= code;
807                 }
808         }
809
810         musb_platform_try_idle(musb, 0);
811
812         spin_unlock_irqrestore(&musb->lock, flags);
813         *eof = 1;
814
815         return buffer - page;
816 }
817
818 void __devexit musb_debug_delete(char *name, struct musb *musb)
819 {
820         if (musb->proc_entry)
821                 remove_proc_entry(name, NULL);
822 }
823
824 struct proc_dir_entry *__init
825 musb_debug_create(char *name, struct musb *data)
826 {
827         struct proc_dir_entry   *pde;
828
829         /* FIXME convert everything to seq_file; then later, debugfs */
830
831         if (!name)
832                 return NULL;
833
834         data->proc_entry = pde = create_proc_entry(name,
835                                         S_IFREG | S_IRUGO | S_IWUSR, NULL);
836         if (pde) {
837                 pde->data = data;
838                 /* pde->owner = THIS_MODULE; */
839
840                 pde->read_proc = musb_proc_read;
841                 pde->write_proc = musb_proc_write;
842
843                 pde->size = 0;
844
845                 pr_debug("Registered /proc/%s\n", name);
846         } else {
847                 pr_debug("Cannot create a valid proc file entry");
848         }
849
850         return pde;
851 }