forked from luck/tmp_suning_uos_patched
cf61fdb944
The struct fhci_regs (in drivers/usb/host/fhci.h) is basically a redefinition of the struct qe_usb_ctlr (in arch/powerpc/include/asm/immap_qe.h). The qe_usb_ctlr struct is preferrable once it uses accurately the registers' names found in the Freescale's QUICC Engine Block Reference Manuals (QEIWRM.pdf Rev.4.4 Chapter 19 for MPC836xE series and MPC8323ERM.pdf Rev.2 Chapter 36 for MPC832xE series), making easier to map the FHCI device driver to the hardware manual. Also, as the FHCI driver uses the USB Controller registers, the name qe_usb_ctlr is a more precise representation of the hardware than fhci_regs. Signed-off-by: Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
140 lines
3.6 KiB
C
140 lines
3.6 KiB
C
/*
|
|
* Freescale QUICC Engine USB Host Controller Driver
|
|
*
|
|
* Copyright (c) Freescale Semicondutor, Inc. 2006.
|
|
* Shlomi Gridish <gridish@freescale.com>
|
|
* Jerry Huang <Chang-Ming.Huang@freescale.com>
|
|
* Copyright (c) Logic Product Development, Inc. 2007
|
|
* Peter Barada <peterb@logicpd.com>
|
|
* Copyright (c) MontaVista Software, Inc. 2008.
|
|
* Anton Vorontsov <avorontsov@ru.mvista.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/usb.h>
|
|
#include <linux/usb/hcd.h>
|
|
#include "fhci.h"
|
|
|
|
void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er)
|
|
{
|
|
int i;
|
|
|
|
if (usb_er == -1) {
|
|
fhci->usb_irq_stat[12]++;
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < 12; ++i) {
|
|
if (usb_er & (1 << i))
|
|
fhci->usb_irq_stat[i]++;
|
|
}
|
|
}
|
|
|
|
static int fhci_dfs_regs_show(struct seq_file *s, void *v)
|
|
{
|
|
struct fhci_hcd *fhci = s->private;
|
|
struct qe_usb_ctlr __iomem *regs = fhci->regs;
|
|
|
|
seq_printf(s,
|
|
"mode: 0x%x\n" "addr: 0x%x\n"
|
|
"command: 0x%x\n" "ep0: 0x%x\n"
|
|
"event: 0x%x\n" "mask: 0x%x\n"
|
|
"status: 0x%x\n" "SOF timer: %d\n"
|
|
"frame number: %d\n"
|
|
"lines status: 0x%x\n",
|
|
in_8(®s->usb_usmod), in_8(®s->usb_usadr),
|
|
in_8(®s->usb_uscom), in_be16(®s->usb_usep[0]),
|
|
in_be16(®s->usb_usber), in_be16(®s->usb_usbmr),
|
|
in_8(®s->usb_usbs), in_be16(®s->usb_ussft),
|
|
in_be16(®s->usb_usfrn),
|
|
fhci_ioports_check_bus_state(fhci));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int fhci_dfs_irq_stat_show(struct seq_file *s, void *v)
|
|
{
|
|
struct fhci_hcd *fhci = s->private;
|
|
int *usb_irq_stat = fhci->usb_irq_stat;
|
|
|
|
seq_printf(s,
|
|
"RXB: %d\n" "TXB: %d\n" "BSY: %d\n"
|
|
"SOF: %d\n" "TXE0: %d\n" "TXE1: %d\n"
|
|
"TXE2: %d\n" "TXE3: %d\n" "IDLE: %d\n"
|
|
"RESET: %d\n" "SFT: %d\n" "MSF: %d\n"
|
|
"IDLE_ONLY: %d\n",
|
|
usb_irq_stat[0], usb_irq_stat[1], usb_irq_stat[2],
|
|
usb_irq_stat[3], usb_irq_stat[4], usb_irq_stat[5],
|
|
usb_irq_stat[6], usb_irq_stat[7], usb_irq_stat[8],
|
|
usb_irq_stat[9], usb_irq_stat[10], usb_irq_stat[11],
|
|
usb_irq_stat[12]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int fhci_dfs_regs_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, fhci_dfs_regs_show, inode->i_private);
|
|
}
|
|
|
|
static int fhci_dfs_irq_stat_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, fhci_dfs_irq_stat_show, inode->i_private);
|
|
}
|
|
|
|
static const struct file_operations fhci_dfs_regs_fops = {
|
|
.open = fhci_dfs_regs_open,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.release = single_release,
|
|
};
|
|
|
|
static const struct file_operations fhci_dfs_irq_stat_fops = {
|
|
.open = fhci_dfs_irq_stat_open,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.release = single_release,
|
|
};
|
|
|
|
void fhci_dfs_create(struct fhci_hcd *fhci)
|
|
{
|
|
struct device *dev = fhci_to_hcd(fhci)->self.controller;
|
|
|
|
fhci->dfs_root = debugfs_create_dir(dev_name(dev), usb_debug_root);
|
|
if (!fhci->dfs_root) {
|
|
WARN_ON(1);
|
|
return;
|
|
}
|
|
|
|
fhci->dfs_regs = debugfs_create_file("regs", S_IFREG | S_IRUGO,
|
|
fhci->dfs_root, fhci, &fhci_dfs_regs_fops);
|
|
|
|
fhci->dfs_irq_stat = debugfs_create_file("irq_stat",
|
|
S_IFREG | S_IRUGO, fhci->dfs_root, fhci,
|
|
&fhci_dfs_irq_stat_fops);
|
|
|
|
WARN_ON(!fhci->dfs_regs || !fhci->dfs_irq_stat);
|
|
}
|
|
|
|
void fhci_dfs_destroy(struct fhci_hcd *fhci)
|
|
{
|
|
if (!fhci->dfs_root)
|
|
return;
|
|
|
|
if (fhci->dfs_irq_stat)
|
|
debugfs_remove(fhci->dfs_irq_stat);
|
|
|
|
if (fhci->dfs_regs)
|
|
debugfs_remove(fhci->dfs_regs);
|
|
|
|
debugfs_remove(fhci->dfs_root);
|
|
}
|