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