Skip to content

Commit

Permalink
xhci: Remove more doorbell-related reads
Browse files Browse the repository at this point in the history
The unused space in the doorbell is now marked as RsvdZ, not RsvdP, so
we can avoid reading the doorbell before writing it.

Update the doorbell-related defines to produce the entire doorbell value
from a single macro.  Document the doorbell format in a comment.

Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
  • Loading branch information
Matthew Wilcox authored and Sarah Sharp committed Jan 14, 2011
1 parent 7961acd commit 50d6467
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 26 deletions.
27 changes: 11 additions & 16 deletions drivers/usb/host/xhci-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,8 @@ static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring,
/* Ring the host controller doorbell after placing a command on the ring */
void xhci_ring_cmd_db(struct xhci_hcd *xhci)
{
u32 temp;

xhci_dbg(xhci, "// Ding dong!\n");
temp = xhci_readl(xhci, &xhci->dba->doorbell[0]) & DB_MASK;
xhci_writel(xhci, temp | DB_TARGET_HOST, &xhci->dba->doorbell[0]);
xhci_writel(xhci, DB_VALUE_HOST, &xhci->dba->doorbell[0]);
/* Flush PCI posted writes */
xhci_readl(xhci, &xhci->dba->doorbell[0]);
}
Expand All @@ -322,26 +319,24 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci,
unsigned int ep_index,
unsigned int stream_id)
{
struct xhci_virt_ep *ep;
unsigned int ep_state;
u32 field;
__u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id];
struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
unsigned int ep_state = ep->ep_state;

ep = &xhci->devs[slot_id]->eps[ep_index];
ep_state = ep->ep_state;
/* Don't ring the doorbell for this endpoint if there are pending
* cancellations because the we don't want to interrupt processing.
* cancellations because we don't want to interrupt processing.
* We don't want to restart any stream rings if there's a set dequeue
* pointer command pending because the device can choose to start any
* stream once the endpoint is on the HW schedule.
* FIXME - check all the stream rings for pending cancellations.
*/
if (!(ep_state & EP_HALT_PENDING) && !(ep_state & SET_DEQ_PENDING)
&& !(ep_state & EP_HALTED)) {
field = xhci_readl(xhci, db_addr) & DB_MASK;
field |= EPI_TO_DB(ep_index) | STREAM_ID_TO_DB(stream_id);
xhci_writel(xhci, field, db_addr);
}
if ((ep_state & EP_HALT_PENDING) || (ep_state & SET_DEQ_PENDING) ||
(ep_state & EP_HALTED))
return;
xhci_writel(xhci, DB_VALUE(ep_index, stream_id), db_addr);
/* The CPU has better things to do at this point than wait for a
* write-posting flush. It'll get there soon enough.
*/
}

/* Ring the doorbell for any rings with pending URBs */
Expand Down
16 changes: 6 additions & 10 deletions drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,22 +436,18 @@ struct xhci_run_regs {
/**
* struct doorbell_array
*
* Bits 0 - 7: Endpoint target
* Bits 8 - 15: RsvdZ
* Bits 16 - 31: Stream ID
*
* Section 5.6
*/
struct xhci_doorbell_array {
u32 doorbell[256];
};

#define DB_TARGET_MASK 0xFFFFFF00
#define DB_STREAM_ID_MASK 0x0000FFFF
#define DB_TARGET_HOST 0x0
#define DB_STREAM_ID_HOST 0x0
#define DB_MASK (0xff << 8)

/* Endpoint Target - bits 0:7 */
#define EPI_TO_DB(p) (((p) + 1) & 0xff)
#define STREAM_ID_TO_DB(p) (((p) & 0xffff) << 16)

#define DB_VALUE(ep, stream) ((((ep) + 1) & 0xff) | ((stream) << 16))
#define DB_VALUE_HOST 0x00000000

/**
* struct xhci_protocol_caps
Expand Down

0 comments on commit 50d6467

Please sign in to comment.