-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Anton Vorontsov
authored and
Greg Kroah-Hartman
committed
Jan 28, 2009
1 parent
fc91be2
commit 236dd4d
Showing
11 changed files
with
3,862 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* 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 "../core/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 fhci_regs __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_mod), in_8(®s->usb_addr), | ||
in_8(®s->usb_comm), in_be16(®s->usb_ep[0]), | ||
in_be16(®s->usb_event), in_be16(®s->usb_mask), | ||
in_8(®s->usb_status), in_be16(®s->usb_sof_tmr), | ||
in_be16(®s->usb_frame_num), | ||
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->bus_id, NULL); | ||
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); | ||
} |
Oops, something went wrong.