aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/fhci-dbg.c
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2009-01-09 21:03:21 -0500
committerGreg Kroah-Hartman <gregkh@kvm.kroah.org>2009-01-27 19:15:38 -0500
commit236dd4d18f293e3c9798f35c08272196826a980d (patch)
tree5e8f7dc48318e82c34758c1a807d034034b96221 /drivers/usb/host/fhci-dbg.c
parentfc91be2ad03e0d243418414a854665274d560ca2 (diff)
USB: Driver for Freescale QUICC Engine USB Host Controller
This patch adds support for the FHCI USB controller, as found in the Freescale MPC836x and MPC832x processors. It can support Full or Low speed modes. Quite a lot the hardware is doing by itself (SOF generation, CRC generation and checking), though scheduling and retransmission is on software's shoulders. This controller does not integrate the root hub, so this driver also fakes one-port hub. External hub is required to support more than one device. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/fhci-dbg.c')
-rw-r--r--drivers/usb/host/fhci-dbg.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/drivers/usb/host/fhci-dbg.c b/drivers/usb/host/fhci-dbg.c
new file mode 100644
index 000000000000..34e14edf390b
--- /dev/null
+++ b/drivers/usb/host/fhci-dbg.c
@@ -0,0 +1,139 @@
1/*
2 * Freescale QUICC Engine USB Host Controller Driver
3 *
4 * Copyright (c) Freescale Semicondutor, Inc. 2006.
5 * Shlomi Gridish <gridish@freescale.com>
6 * Jerry Huang <Chang-Ming.Huang@freescale.com>
7 * Copyright (c) Logic Product Development, Inc. 2007
8 * Peter Barada <peterb@logicpd.com>
9 * Copyright (c) MontaVista Software, Inc. 2008.
10 * Anton Vorontsov <avorontsov@ru.mvista.com>
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18#include <linux/kernel.h>
19#include <linux/errno.h>
20#include <linux/debugfs.h>
21#include <linux/seq_file.h>
22#include <linux/usb.h>
23#include "../core/hcd.h"
24#include "fhci.h"
25
26void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er)
27{
28 int i;
29
30 if (usb_er == -1) {
31 fhci->usb_irq_stat[12]++;
32 return;
33 }
34
35 for (i = 0; i < 12; ++i) {
36 if (usb_er & (1 << i))
37 fhci->usb_irq_stat[i]++;
38 }
39}
40
41static int fhci_dfs_regs_show(struct seq_file *s, void *v)
42{
43 struct fhci_hcd *fhci = s->private;
44 struct fhci_regs __iomem *regs = fhci->regs;
45
46 seq_printf(s,
47 "mode: 0x%x\n" "addr: 0x%x\n"
48 "command: 0x%x\n" "ep0: 0x%x\n"
49 "event: 0x%x\n" "mask: 0x%x\n"
50 "status: 0x%x\n" "SOF timer: %d\n"
51 "frame number: %d\n"
52 "lines status: 0x%x\n",
53 in_8(&regs->usb_mod), in_8(&regs->usb_addr),
54 in_8(&regs->usb_comm), in_be16(&regs->usb_ep[0]),
55 in_be16(&regs->usb_event), in_be16(&regs->usb_mask),
56 in_8(&regs->usb_status), in_be16(&regs->usb_sof_tmr),
57 in_be16(&regs->usb_frame_num),
58 fhci_ioports_check_bus_state(fhci));
59
60 return 0;
61}
62
63static int fhci_dfs_irq_stat_show(struct seq_file *s, void *v)
64{
65 struct fhci_hcd *fhci = s->private;
66 int *usb_irq_stat = fhci->usb_irq_stat;
67
68 seq_printf(s,
69 "RXB: %d\n" "TXB: %d\n" "BSY: %d\n"
70 "SOF: %d\n" "TXE0: %d\n" "TXE1: %d\n"
71 "TXE2: %d\n" "TXE3: %d\n" "IDLE: %d\n"
72 "RESET: %d\n" "SFT: %d\n" "MSF: %d\n"
73 "IDLE_ONLY: %d\n",
74 usb_irq_stat[0], usb_irq_stat[1], usb_irq_stat[2],
75 usb_irq_stat[3], usb_irq_stat[4], usb_irq_stat[5],
76 usb_irq_stat[6], usb_irq_stat[7], usb_irq_stat[8],
77 usb_irq_stat[9], usb_irq_stat[10], usb_irq_stat[11],
78 usb_irq_stat[12]);
79
80 return 0;
81}
82
83static int fhci_dfs_regs_open(struct inode *inode, struct file *file)
84{
85 return single_open(file, fhci_dfs_regs_show, inode->i_private);
86}
87
88static int fhci_dfs_irq_stat_open(struct inode *inode, struct file *file)
89{
90 return single_open(file, fhci_dfs_irq_stat_show, inode->i_private);
91}
92
93static const struct file_operations fhci_dfs_regs_fops = {
94 .open = fhci_dfs_regs_open,
95 .read = seq_read,
96 .llseek = seq_lseek,
97 .release = single_release,
98};
99
100static const struct file_operations fhci_dfs_irq_stat_fops = {
101 .open = fhci_dfs_irq_stat_open,
102 .read = seq_read,
103 .llseek = seq_lseek,
104 .release = single_release,
105};
106
107void fhci_dfs_create(struct fhci_hcd *fhci)
108{
109 struct device *dev = fhci_to_hcd(fhci)->self.controller;
110
111 fhci->dfs_root = debugfs_create_dir(dev->bus_id, NULL);
112 if (!fhci->dfs_root) {
113 WARN_ON(1);
114 return;
115 }
116
117 fhci->dfs_regs = debugfs_create_file("regs", S_IFREG | S_IRUGO,
118 fhci->dfs_root, fhci, &fhci_dfs_regs_fops);
119
120 fhci->dfs_irq_stat = debugfs_create_file("irq_stat",
121 S_IFREG | S_IRUGO, fhci->dfs_root, fhci,
122 &fhci_dfs_irq_stat_fops);
123
124 WARN_ON(!fhci->dfs_regs || !fhci->dfs_irq_stat);
125}
126
127void fhci_dfs_destroy(struct fhci_hcd *fhci)
128{
129 if (!fhci->dfs_root)
130 return;
131
132 if (fhci->dfs_irq_stat)
133 debugfs_remove(fhci->dfs_irq_stat);
134
135 if (fhci->dfs_regs)
136 debugfs_remove(fhci->dfs_regs);
137
138 debugfs_remove(fhci->dfs_root);
139}