diff options
Diffstat (limited to 'recipes/linux/linux-omap-2.6.31/usb/0012-musb-Add-back-old-musb-procfs-file.patch')
-rw-r--r-- | recipes/linux/linux-omap-2.6.31/usb/0012-musb-Add-back-old-musb-procfs-file.patch | 947 |
1 files changed, 947 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-2.6.31/usb/0012-musb-Add-back-old-musb-procfs-file.patch b/recipes/linux/linux-omap-2.6.31/usb/0012-musb-Add-back-old-musb-procfs-file.patch new file mode 100644 index 0000000000..bc1ad5a648 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0012-musb-Add-back-old-musb-procfs-file.patch @@ -0,0 +1,947 @@ +From 7f43c6297c781c2d403ee397fe2cfccaaf3eea42 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta <ajay.gupta@ti.com> +Date: Sat, 20 Jun 2009 14:06:38 +0530 +Subject: [PATCH 12/16] musb: Add back old musb procfs file + +Procfs file is removed from musb and an equivalent debugfs is +expected to replace it. + +Adding the old file back to retain the debug functionalities untill +we get debugfs equivalent in mainline. + +Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com> +--- + drivers/usb/musb/Makefile | 3 + + drivers/usb/musb/musb_core.c | 8 +- + drivers/usb/musb/musb_core.h | 19 + + drivers/usb/musb/musb_procfs.c | 838 ++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 863 insertions(+), 5 deletions(-) + create mode 100644 drivers/usb/musb/musb_procfs.c + +diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile +index 85710cc..06969c5 100644 +--- a/drivers/usb/musb/Makefile ++++ b/drivers/usb/musb/Makefile +@@ -74,4 +74,7 @@ endif + + ifeq ($(CONFIG_USB_MUSB_DEBUG),y) + EXTRA_CFLAGS += -DDEBUG ++ ifeq ($(CONFIG_PROC_FS),y) ++ musb_hdrc-objs += musb_procfs.o ++ endif + endif +diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c +index 129f9dc..f5ca435 100644 +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -2046,8 +2046,6 @@ bad_config: + musb->xceiv->state = OTG_STATE_A_IDLE; + + status = usb_add_hcd(musb_to_hcd(musb), -1, 0); +- if (status) +- goto fail; + + DBG(1, "%s mode, status %d, devctl %02x %c\n", + "HOST", status, +@@ -2062,8 +2060,6 @@ bad_config: + musb->xceiv->state = OTG_STATE_B_IDLE; + + status = musb_gadget_setup(musb); +- if (status) +- goto fail; + + DBG(1, "%s mode, status %d, dev%02x\n", + is_otg_enabled(musb) ? "OTG" : "PERIPHERAL", +@@ -2082,7 +2078,8 @@ bad_config: + #endif + if (status) + goto fail2; +- ++ if (status == 0) ++ musb_debug_create("driver/musb_hdrc", musb); + return 0; + + fail2: +@@ -2152,6 +2149,7 @@ static int __devexit musb_remove(struct platform_device *pdev) + * - OTG mode: both roles are deactivated (or never-activated) + */ + musb_shutdown(pdev); ++ musb_debug_delete("driver/musb_hdrc", musb); + #ifdef CONFIG_USB_MUSB_HDRC_HCD + if (musb->board_mode == MUSB_HOST) + usb_remove_hcd(musb_to_hcd(musb)); +diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h +index 381d648..b0b4fbd 100644 +--- a/drivers/usb/musb/musb_core.h ++++ b/drivers/usb/musb/musb_core.h +@@ -562,4 +562,23 @@ extern int musb_platform_get_vbus_status(struct musb *musb); + extern int __init musb_platform_init(struct musb *musb); + extern int musb_platform_exit(struct musb *musb); + ++/*-------------------------- ProcFS definitions ---------------------*/ ++ ++struct proc_dir_entry; ++ ++#if (CONFIG_USB_MUSB_DEBUG > 0) && defined(MUSB_CONFIG_PROC_FS) ++extern struct proc_dir_entry *musb_debug_create(char *name, struct musb *data); ++extern void musb_debug_delete(char *name, struct musb *data); ++ ++#else ++static inline struct proc_dir_entry * ++musb_debug_create(char *name, struct musb *data) ++{ ++ return NULL; ++} ++static inline void musb_debug_delete(char *name, struct musb *data) ++{ ++} ++#endif ++ + #endif /* __MUSB_CORE_H__ */ +diff --git a/drivers/usb/musb/musb_procfs.c b/drivers/usb/musb/musb_procfs.c +new file mode 100644 +index 0000000..d789d4d +--- /dev/null ++++ b/drivers/usb/musb/musb_procfs.c +@@ -0,0 +1,838 @@ ++/* ++ * MUSB OTG driver debug support ++ * ++ * Copyright 2005 Mentor Graphics Corporation ++ * Copyright (C) 2005-2006 by Texas Instruments ++ * Copyright (C) 2006-2007 Nokia Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301 USA ++ * ++ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/proc_fs.h> ++#include <linux/seq_file.h> ++#include <linux/uaccess.h> /* FIXME remove procfs writes */ ++#include <mach/hardware.h> ++ ++#include "musb_core.h" ++ ++#include "davinci.h" ++ ++#ifdef CONFIG_USB_MUSB_HDRC_HCD ++ ++static int dump_qh(struct musb_qh *qh, char *buf, unsigned max) ++{ ++ int count; ++ int tmp; ++ struct usb_host_endpoint *hep = qh->hep; ++ struct urb *urb; ++ ++ count = snprintf(buf, max, " qh %p dev%d ep%d%s max%d\n", ++ qh, qh->dev->devnum, qh->epnum, ++ ({ char *s; switch (qh->type) { ++ case USB_ENDPOINT_XFER_BULK: ++ s = "-bulk"; break; ++ case USB_ENDPOINT_XFER_INT: ++ s = "-int"; break; ++ case USB_ENDPOINT_XFER_CONTROL: ++ s = ""; break; ++ default: ++ s = "iso"; break; ++ }; s; }), ++ qh->maxpacket); ++ if (count <= 0) ++ return 0; ++ buf += count; ++ max -= count; ++ ++ list_for_each_entry(urb, &hep->urb_list, urb_list) { ++ tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n", ++ usb_pipein(urb->pipe) ? "in" : "out", ++ urb, urb->actual_length, ++ urb->transfer_buffer_length); ++ if (tmp <= 0) ++ break; ++ tmp = min(tmp, (int)max); ++ count += tmp; ++ buf += tmp; ++ max -= tmp; ++ } ++ return count; ++} ++ ++static int ++dump_queue(struct list_head *q, char *buf, unsigned max) ++{ ++ int count = 0; ++ struct musb_qh *qh; ++ ++ list_for_each_entry(qh, q, ring) { ++ int tmp; ++ ++ tmp = dump_qh(qh, buf, max); ++ if (tmp <= 0) ++ break; ++ tmp = min(tmp, (int)max); ++ count += tmp; ++ buf += tmp; ++ max -= tmp; ++ } ++ return count; ++} ++ ++#endif /* HCD */ ++ ++#ifdef CONFIG_USB_GADGET_MUSB_HDRC ++static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max) ++{ ++ char *buf = buffer; ++ int code = 0; ++ void __iomem *regs = ep->hw_ep->regs; ++ char *mode = "1buf"; ++ ++ if (ep->is_in) { ++ if (ep->hw_ep->tx_double_buffered) ++ mode = "2buf"; ++ } else { ++ if (ep->hw_ep->rx_double_buffered) ++ mode = "2buf"; ++ } ++ ++ do { ++ struct usb_request *req; ++ ++ code = snprintf(buf, max, ++ "\n%s (hw%d): %s%s, csr %04x maxp %04x\n", ++ ep->name, ep->current_epnum, ++ mode, ep->dma ? " dma" : "", ++ musb_readw(regs, ++ (ep->is_in || !ep->current_epnum) ++ ? MUSB_TXCSR ++ : MUSB_RXCSR), ++ musb_readw(regs, ep->is_in ++ ? MUSB_TXMAXP ++ : MUSB_RXMAXP) ++ ); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ ++ if (is_cppi_enabled() && ep->current_epnum) { ++ unsigned cppi = ep->current_epnum - 1; ++ void __iomem *base = ep->musb->ctrl_base; ++ unsigned off1 = cppi << 2; ++ void __iomem *ram = base; ++ char tmp[16]; ++ ++ if (ep->is_in) { ++ ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi); ++ tmp[0] = 0; ++ } else { ++ ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi); ++ snprintf(tmp, sizeof tmp, "%d left, ", ++ musb_readl(base, ++ DAVINCI_RXCPPI_BUFCNT0_REG + off1)); ++ } ++ ++ code = snprintf(buf, max, "%cX DMA%d: %s" ++ "%08x %08x, %08x %08x; " ++ "%08x %08x %08x .. %08x\n", ++ ep->is_in ? 'T' : 'R', ++ ep->current_epnum - 1, tmp, ++ musb_readl(ram, 0 * 4), ++ musb_readl(ram, 1 * 4), ++ musb_readl(ram, 2 * 4), ++ musb_readl(ram, 3 * 4), ++ musb_readl(ram, 4 * 4), ++ musb_readl(ram, 5 * 4), ++ musb_readl(ram, 6 * 4), ++ musb_readl(ram, 7 * 4)); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ ++ if (list_empty(&ep->req_list)) { ++ code = snprintf(buf, max, "\t(queue empty)\n"); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ break; ++ } ++ list_for_each_entry(req, &ep->req_list, list) { ++ code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n", ++ req, ++ req->zero ? "zero, " : "", ++ req->short_not_ok ? "!short, " : "", ++ req->actual, req->length); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ } while (0); ++ return buf - buffer; ++} ++#endif ++ ++static int ++dump_end_info(struct musb *musb, u8 epnum, char *aBuffer, unsigned max) ++{ ++ int code = 0; ++ char *buf = aBuffer; ++ struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; ++ ++ do { ++ musb_ep_select(musb->mregs, epnum); ++#ifdef CONFIG_USB_MUSB_HDRC_HCD ++ if (is_host_active(musb)) { ++ int dump_rx, dump_tx; ++ void __iomem *regs = hw_ep->regs; ++ ++ /* TEMPORARY (!) until we have a real periodic ++ * schedule tree ... ++ */ ++ if (!epnum) { ++ /* control is shared, uses RX queue ++ * but (mostly) shadowed tx registers ++ */ ++ dump_tx = !list_empty(&musb->control); ++ dump_rx = 0; ++ } else if (hw_ep == musb->bulk_ep) { ++ dump_tx = !list_empty(&musb->out_bulk); ++ dump_rx = !list_empty(&musb->in_bulk); ++ } else if (hw_ep->in_qh || hw_ep->out_qh) { ++ if (hw_ep->in_qh) ++ dump_rx = 1; ++ else ++ dump_rx = 0; ++ dump_tx = !dump_rx; ++ } else ++ break; ++ /* END TEMPORARY */ ++ ++ ++ if (dump_rx) { ++ code = snprintf(buf, max, ++ "\nRX%d: %s rxcsr %04x interval %02x " ++ "max %04x type %02x; " ++ "dev %d hub %d port %d" ++ "\n", ++ epnum, ++ hw_ep->rx_double_buffered ++ ? "2buf" : "1buf", ++ musb_readw(regs, MUSB_RXCSR), ++ musb_readb(regs, MUSB_RXINTERVAL), ++ musb_readw(regs, MUSB_RXMAXP), ++ musb_readb(regs, MUSB_RXTYPE), ++ /* FIXME: assumes multipoint */ ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_RXFUNCADDR)), ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_RXHUBADDR)), ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_RXHUBPORT)) ++ ); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ ++ if (is_cppi_enabled() ++ && epnum ++ && hw_ep->rx_channel) { ++ unsigned cppi = epnum - 1; ++ unsigned off1 = cppi << 2; ++ void __iomem *base; ++ void __iomem *ram; ++ char tmp[16]; ++ ++ base = musb->ctrl_base; ++ ram = DAVINCI_RXCPPI_STATERAM_OFFSET( ++ cppi) + base; ++ snprintf(tmp, sizeof tmp, "%d left, ", ++ musb_readl(base, ++ DAVINCI_RXCPPI_BUFCNT0_REG ++ + off1)); ++ ++ code = snprintf(buf, max, ++ " rx dma%d: %s" ++ "%08x %08x, %08x %08x; " ++ "%08x %08x %08x .. %08x\n", ++ cppi, tmp, ++ musb_readl(ram, 0 * 4), ++ musb_readl(ram, 1 * 4), ++ musb_readl(ram, 2 * 4), ++ musb_readl(ram, 3 * 4), ++ musb_readl(ram, 4 * 4), ++ musb_readl(ram, 5 * 4), ++ musb_readl(ram, 6 * 4), ++ musb_readl(ram, 7 * 4)); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ ++ if (hw_ep == musb->bulk_ep ++ && !list_empty( ++ &musb->in_bulk)) { ++ code = dump_queue(&musb->in_bulk, ++ buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } else if (hw_ep->in_qh) { ++ code = dump_qh(hw_ep->in_qh, ++ buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ } ++ ++ if (dump_tx) { ++ code = snprintf(buf, max, ++ "\nTX%d: %s txcsr %04x interval %02x " ++ "max %04x type %02x; " ++ "dev %d hub %d port %d" ++ "\n", ++ epnum, ++ hw_ep->tx_double_buffered ++ ? "2buf" : "1buf", ++ musb_readw(regs, MUSB_TXCSR), ++ musb_readb(regs, MUSB_TXINTERVAL), ++ musb_readw(regs, MUSB_TXMAXP), ++ musb_readb(regs, MUSB_TXTYPE), ++ /* FIXME: assumes multipoint */ ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_TXFUNCADDR)), ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_TXHUBADDR)), ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_TXHUBPORT)) ++ ); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ ++ if (is_cppi_enabled() ++ && epnum ++ && hw_ep->tx_channel) { ++ unsigned cppi = epnum - 1; ++ void __iomem *base; ++ void __iomem *ram; ++ ++ base = musb->ctrl_base; ++ ram = DAVINCI_RXCPPI_STATERAM_OFFSET( ++ cppi) + base; ++ code = snprintf(buf, max, ++ " tx dma%d: " ++ "%08x %08x, %08x %08x; " ++ "%08x %08x %08x .. %08x\n", ++ cppi, ++ musb_readl(ram, 0 * 4), ++ musb_readl(ram, 1 * 4), ++ musb_readl(ram, 2 * 4), ++ musb_readl(ram, 3 * 4), ++ musb_readl(ram, 4 * 4), ++ musb_readl(ram, 5 * 4), ++ musb_readl(ram, 6 * 4), ++ musb_readl(ram, 7 * 4)); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ ++ if (hw_ep == musb->control_ep ++ && !list_empty( ++ &musb->control)) { ++ code = dump_queue(&musb->control, ++ buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } else if (hw_ep == musb->bulk_ep ++ && !list_empty( ++ &musb->out_bulk)) { ++ code = dump_queue(&musb->out_bulk, ++ buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } else if (hw_ep->out_qh) { ++ code = dump_qh(hw_ep->out_qh, ++ buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ } ++ } ++#endif ++#ifdef CONFIG_USB_GADGET_MUSB_HDRC ++ if (is_peripheral_active(musb)) { ++ code = 0; ++ ++ if (hw_ep->ep_in.desc || !epnum) { ++ code = dump_ep(&hw_ep->ep_in, buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ if (hw_ep->ep_out.desc) { ++ code = dump_ep(&hw_ep->ep_out, buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ } ++#endif ++ } while (0); ++ ++ return buf - aBuffer; ++} ++ ++/* Dump the current status and compile options. ++ * @param musb the device driver instance ++ * @param buffer where to dump the status; it must be big enough to hold the ++ * result otherwise "BAD THINGS HAPPENS(TM)". ++ */ ++static int dump_header_stats(struct musb *musb, char *buffer) ++{ ++ int code, count = 0; ++ const void __iomem *mbase = musb->mregs; ++ ++ *buffer = 0; ++ count = sprintf(buffer, "Status: %sHDRC, Mode=%s " ++ "(Power=%02x, DevCtl=%02x)\n", ++ (musb->is_multipoint ? "M" : ""), MUSB_MODE(musb), ++ musb_readb(mbase, MUSB_POWER), ++ musb_readb(mbase, MUSB_DEVCTL)); ++ if (count <= 0) ++ return 0; ++ buffer += count; ++ ++ code = sprintf(buffer, "OTG state: %s; %sactive\n", ++ otg_state_string(musb), ++ musb->is_active ? "" : "in"); ++ if (code <= 0) ++ goto done; ++ buffer += code; ++ count += code; ++ ++ code = sprintf(buffer, ++ "Options: " ++#ifdef CONFIG_MUSB_PIO_ONLY ++ "pio" ++#elif defined(CONFIG_USB_TI_CPPI_DMA) ++ "cppi-dma" ++#elif defined(CONFIG_USB_INVENTRA_DMA) ++ "musb-dma" ++#elif defined(CONFIG_USB_TUSB_OMAP_DMA) ++ "tusb-omap-dma" ++#else ++ "?dma?" ++#endif ++ ", " ++#ifdef CONFIG_USB_MUSB_OTG ++ "otg (peripheral+host)" ++#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) ++ "peripheral" ++#elif defined(CONFIG_USB_MUSB_HDRC_HCD) ++ "host" ++#endif ++ ", debug=%d [eps=%d]\n", ++ musb_debug, ++ musb->nr_endpoints); ++ if (code <= 0) ++ goto done; ++ count += code; ++ buffer += code; ++ ++#ifdef CONFIG_USB_GADGET_MUSB_HDRC ++ code = sprintf(buffer, "Peripheral address: %02x\n", ++ musb_readb(musb->ctrl_base, MUSB_FADDR)); ++ if (code <= 0) ++ goto done; ++ buffer += code; ++ count += code; ++#endif ++ ++#ifdef CONFIG_USB_MUSB_HDRC_HCD ++ code = sprintf(buffer, "Root port status: %08x\n", ++ musb->port1_status); ++ if (code <= 0) ++ goto done; ++ buffer += code; ++ count += code; ++#endif ++ ++#ifdef CONFIG_ARCH_DAVINCI ++ code = sprintf(buffer, ++ "DaVinci: ctrl=%02x stat=%1x phy=%03x\n" ++ "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x" ++ "\n", ++ musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG), ++ musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG), ++ __raw_readl((void __force __iomem *) ++ IO_ADDRESS(USBPHY_CTL_PADDR)), ++ musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG), ++ musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_USB_INT_SOURCE_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_USB_INT_MASK_REG)); ++ if (code <= 0) ++ goto done; ++ count += code; ++ buffer += code; ++#endif /* DAVINCI */ ++ ++#ifdef CONFIG_USB_TUSB6010 ++ code = sprintf(buffer, ++ "TUSB6010: devconf %08x, phy enable %08x drive %08x" ++ "\n\totg %03x timer %08x" ++ "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x" ++ "\n", ++ musb_readl(musb->ctrl_base, TUSB_DEV_CONF), ++ musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE), ++ musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL), ++ musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT), ++ musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER), ++ musb_readl(musb->ctrl_base, TUSB_PRCM_CONF), ++ musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT), ++ musb_readl(musb->ctrl_base, TUSB_INT_SRC), ++ musb_readl(musb->ctrl_base, TUSB_INT_MASK)); ++ if (code <= 0) ++ goto done; ++ count += code; ++ buffer += code; ++#endif /* DAVINCI */ ++ ++ if (is_cppi_enabled() && musb->dma_controller) { ++ code = sprintf(buffer, ++ "CPPI: txcr=%d txsrc=%01x txena=%01x; " ++ "rxcr=%d rxsrc=%01x rxena=%01x " ++ "\n", ++ musb_readl(musb->ctrl_base, ++ DAVINCI_TXCPPI_CTRL_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_TXCPPI_RAW_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_TXCPPI_INTENAB_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_RXCPPI_CTRL_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_RXCPPI_RAW_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_RXCPPI_INTENAB_REG)); ++ if (code <= 0) ++ goto done; ++ count += code; ++ buffer += code; ++ } ++ ++#ifdef CONFIG_USB_GADGET_MUSB_HDRC ++ if (is_peripheral_enabled(musb)) { ++ code = sprintf(buffer, "Gadget driver: %s\n", ++ musb->gadget_driver ++ ? musb->gadget_driver->driver.name ++ : "(none)"); ++ if (code <= 0) ++ goto done; ++ count += code; ++ buffer += code; ++ } ++#endif ++ ++done: ++ return count; ++} ++ ++/* Write to ProcFS ++ * ++ * C soft-connect ++ * c soft-disconnect ++ * I enable HS ++ * i disable HS ++ * s stop session ++ * F force session (OTG-unfriendly) ++ * E rElinquish bus (OTG) ++ * H request host mode ++ * h cancel host request ++ * T start sending TEST_PACKET ++ * D<num> set/query the debug level ++ */ ++static int musb_proc_write(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ char cmd; ++ u8 reg; ++ struct musb *musb = (struct musb *)data; ++ void __iomem *mbase = musb->mregs; ++ ++ /* MOD_INC_USE_COUNT; */ ++ ++ if (unlikely(copy_from_user(&cmd, buffer, 1))) ++ return -EFAULT; ++ ++ switch (cmd) { ++ case 'S': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_POWER) ++ | MUSB_POWER_SUSPENDM; ++ musb_writeb(mbase, MUSB_POWER, reg); ++ } ++ break; ++ ++ case 'C': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_POWER) ++ | MUSB_POWER_SOFTCONN; ++ musb_writeb(mbase, MUSB_POWER, reg); ++ } ++ break; ++ ++ case 'c': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_POWER) ++ & ~MUSB_POWER_SOFTCONN; ++ musb_writeb(mbase, MUSB_POWER, reg); ++ } ++ break; ++ ++ case 'I': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_POWER) ++ | MUSB_POWER_HSENAB; ++ musb_writeb(mbase, MUSB_POWER, reg); ++ } ++ break; ++ ++ case 'i': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_POWER) ++ & ~MUSB_POWER_HSENAB; ++ musb_writeb(mbase, MUSB_POWER, reg); ++ } ++ break; ++ ++ case 'F': ++ reg = musb_readb(mbase, MUSB_DEVCTL); ++ reg |= MUSB_DEVCTL_SESSION; ++ musb_writeb(mbase, MUSB_DEVCTL, reg); ++ break; ++ ++ case 'H': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_DEVCTL); ++ reg |= MUSB_DEVCTL_HR; ++ musb_writeb(mbase, MUSB_DEVCTL, reg); ++ /* MUSB_HST_MODE( ((struct musb*)data) ); */ ++ /* WARNING("Host Mode\n"); */ ++ } ++ break; ++ ++ case 'h': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_DEVCTL); ++ reg &= ~MUSB_DEVCTL_HR; ++ musb_writeb(mbase, MUSB_DEVCTL, reg); ++ } ++ break; ++ ++ case 'T': ++ if (mbase) { ++ musb_load_testpacket(musb); ++ musb_writeb(mbase, MUSB_TESTMODE, ++ MUSB_TEST_PACKET); ++ } ++ break; ++ ++#if (CONFIG_USB_MUSB_DEBUG > 0) ++ /* set/read debug level */ ++ case 'D':{ ++ if (count > 1) { ++ char digits[8], *p = digits; ++ int i = 0, level = 0, sign = 1; ++ int len = min(count - 1, (unsigned long)8); ++ ++ if (copy_from_user(&digits, &buffer[1], len)) ++ return -EFAULT; ++ ++ /* optional sign */ ++ if (*p == '-') { ++ len -= 1; ++ sign = -sign; ++ p++; ++ } ++ ++ /* read it */ ++ while (i++ < len && *p > '0' && *p < '9') { ++ level = level * 10 + (*p - '0'); ++ p++; ++ } ++ ++ level *= sign; ++ DBG(1, "debug level %d\n", level); ++ musb_debug = level; ++ } ++ } ++ break; ++ ++ ++ case '?': ++ INFO("?: you are seeing it\n"); ++ INFO("S: suspend the usb bus\n"); ++ INFO("C/c: soft connect enable/disable\n"); ++ INFO("I/i: hispeed enable/disable\n"); ++ INFO("F: force session start\n"); ++ INFO("H: host mode\n"); ++ INFO("T: start sending TEST_PACKET\n"); ++ INFO("D: set/read dbug level\n"); ++ break; ++#endif ++ ++ default: ++ ERR("Command %c not implemented\n", cmd); ++ break; ++ } ++ ++ musb_platform_try_idle(musb, 0); ++ ++ return count; ++} ++ ++static int musb_proc_read(char *page, char **start, ++ off_t off, int count, int *eof, void *data) ++{ ++ char *buffer = page; ++ int code = 0; ++ unsigned long flags; ++ struct musb *musb = data; ++ unsigned epnum; ++ ++ count -= off; ++ count -= 1; /* for NUL at end */ ++ if (count <= 0) ++ return -EINVAL; ++ ++ spin_lock_irqsave(&musb->lock, flags); ++ ++ code = dump_header_stats(musb, buffer); ++ if (code > 0) { ++ buffer += code; ++ count -= code; ++ } ++ ++ /* generate the report for the end points */ ++ /* REVISIT ... not unless something's connected! */ ++ for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints; ++ epnum++) { ++ code = dump_end_info(musb, epnum, buffer, count); ++ if (code > 0) { ++ buffer += code; ++ count -= code; ++ } ++ } ++ ++ musb_platform_try_idle(musb, 0); ++ ++ spin_unlock_irqrestore(&musb->lock, flags); ++ *eof = 1; ++ ++ return buffer - page; ++} ++ ++void __devexit musb_debug_delete(char *name, struct musb *musb) ++{ ++ if (musb->proc_entry) ++ remove_proc_entry(name, NULL); ++} ++ ++struct proc_dir_entry *__init ++musb_debug_create(char *name, struct musb *data) ++{ ++ struct proc_dir_entry *pde; ++ ++ /* FIXME convert everything to seq_file; then later, debugfs */ ++ ++ if (!name) ++ return NULL; ++ ++ pde = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, NULL); ++ data->proc_entry = pde; ++ if (pde) { ++ pde->data = data; ++ /* pde->owner = THIS_MODULE; */ ++ ++ pde->read_proc = musb_proc_read; ++ pde->write_proc = musb_proc_write; ++ ++ pde->size = 0; ++ ++ pr_debug("Registered /proc/%s\n", name); ++ } else { ++ pr_debug("Cannot create a valid proc file entry"); ++ } ++ ++ return pde; ++} +-- +1.6.2.4 + |