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