diff options
author | Matthew Wilcox <matthew@wil.cx> | 2010-12-15 14:18:11 -0500 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2011-01-14 18:52:00 -0500 |
commit | 50d64676d132a8a72a1a1657d7b3e6efa53da1ac (patch) | |
tree | b2c5b85f15e4068d29fd41d2e6e65f81dd7339d5 /drivers | |
parent | 7961acd7327fe48e55abef277630abdbb3f2081a (diff) |
xhci: Remove more doorbell-related reads
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 27 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 16 |
2 files changed, 17 insertions, 26 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 2116c0f64952..3e8211c1ce5a 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -308,11 +308,8 @@ static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring, | |||
308 | /* Ring the host controller doorbell after placing a command on the ring */ | 308 | /* Ring the host controller doorbell after placing a command on the ring */ |
309 | void xhci_ring_cmd_db(struct xhci_hcd *xhci) | 309 | void xhci_ring_cmd_db(struct xhci_hcd *xhci) |
310 | { | 310 | { |
311 | u32 temp; | ||
312 | |||
313 | xhci_dbg(xhci, "// Ding dong!\n"); | 311 | xhci_dbg(xhci, "// Ding dong!\n"); |
314 | temp = xhci_readl(xhci, &xhci->dba->doorbell[0]) & DB_MASK; | 312 | xhci_writel(xhci, DB_VALUE_HOST, &xhci->dba->doorbell[0]); |
315 | xhci_writel(xhci, temp | DB_TARGET_HOST, &xhci->dba->doorbell[0]); | ||
316 | /* Flush PCI posted writes */ | 313 | /* Flush PCI posted writes */ |
317 | xhci_readl(xhci, &xhci->dba->doorbell[0]); | 314 | xhci_readl(xhci, &xhci->dba->doorbell[0]); |
318 | } | 315 | } |
@@ -322,26 +319,24 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, | |||
322 | unsigned int ep_index, | 319 | unsigned int ep_index, |
323 | unsigned int stream_id) | 320 | unsigned int stream_id) |
324 | { | 321 | { |
325 | struct xhci_virt_ep *ep; | ||
326 | unsigned int ep_state; | ||
327 | u32 field; | ||
328 | __u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id]; | 322 | __u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id]; |
323 | struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index]; | ||
324 | unsigned int ep_state = ep->ep_state; | ||
329 | 325 | ||
330 | ep = &xhci->devs[slot_id]->eps[ep_index]; | ||
331 | ep_state = ep->ep_state; | ||
332 | /* Don't ring the doorbell for this endpoint if there are pending | 326 | /* Don't ring the doorbell for this endpoint if there are pending |
333 | * cancellations because the we don't want to interrupt processing. | 327 | * cancellations because we don't want to interrupt processing. |
334 | * We don't want to restart any stream rings if there's a set dequeue | 328 | * We don't want to restart any stream rings if there's a set dequeue |
335 | * pointer command pending because the device can choose to start any | 329 | * pointer command pending because the device can choose to start any |
336 | * stream once the endpoint is on the HW schedule. | 330 | * stream once the endpoint is on the HW schedule. |
337 | * FIXME - check all the stream rings for pending cancellations. | 331 | * FIXME - check all the stream rings for pending cancellations. |
338 | */ | 332 | */ |
339 | if (!(ep_state & EP_HALT_PENDING) && !(ep_state & SET_DEQ_PENDING) | 333 | if ((ep_state & EP_HALT_PENDING) || (ep_state & SET_DEQ_PENDING) || |
340 | && !(ep_state & EP_HALTED)) { | 334 | (ep_state & EP_HALTED)) |
341 | field = xhci_readl(xhci, db_addr) & DB_MASK; | 335 | return; |
342 | field |= EPI_TO_DB(ep_index) | STREAM_ID_TO_DB(stream_id); | 336 | xhci_writel(xhci, DB_VALUE(ep_index, stream_id), db_addr); |
343 | xhci_writel(xhci, field, db_addr); | 337 | /* The CPU has better things to do at this point than wait for a |
344 | } | 338 | * write-posting flush. It'll get there soon enough. |
339 | */ | ||
345 | } | 340 | } |
346 | 341 | ||
347 | /* Ring the doorbell for any rings with pending URBs */ | 342 | /* Ring the doorbell for any rings with pending URBs */ |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 170c367112d2..7f236fd22015 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -436,22 +436,18 @@ struct xhci_run_regs { | |||
436 | /** | 436 | /** |
437 | * struct doorbell_array | 437 | * struct doorbell_array |
438 | * | 438 | * |
439 | * Bits 0 - 7: Endpoint target | ||
440 | * Bits 8 - 15: RsvdZ | ||
441 | * Bits 16 - 31: Stream ID | ||
442 | * | ||
439 | * Section 5.6 | 443 | * Section 5.6 |
440 | */ | 444 | */ |
441 | struct xhci_doorbell_array { | 445 | struct xhci_doorbell_array { |
442 | u32 doorbell[256]; | 446 | u32 doorbell[256]; |
443 | }; | 447 | }; |
444 | 448 | ||
445 | #define DB_TARGET_MASK 0xFFFFFF00 | 449 | #define DB_VALUE(ep, stream) ((((ep) + 1) & 0xff) | ((stream) << 16)) |
446 | #define DB_STREAM_ID_MASK 0x0000FFFF | 450 | #define DB_VALUE_HOST 0x00000000 |
447 | #define DB_TARGET_HOST 0x0 | ||
448 | #define DB_STREAM_ID_HOST 0x0 | ||
449 | #define DB_MASK (0xff << 8) | ||
450 | |||
451 | /* Endpoint Target - bits 0:7 */ | ||
452 | #define EPI_TO_DB(p) (((p) + 1) & 0xff) | ||
453 | #define STREAM_ID_TO_DB(p) (((p) & 0xffff) << 16) | ||
454 | |||
455 | 451 | ||
456 | /** | 452 | /** |
457 | * struct xhci_protocol_caps | 453 | * struct xhci_protocol_caps |