diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2012-05-24 13:29:19 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2012-05-27 06:31:11 -0400 |
commit | 9d60ef2bd87f201c509cfae13ba6c9013446673d (patch) | |
tree | 76c4c28d674d33c924f638cde404bfafede88e15 /drivers/firewire/ohci.c | |
parent | f07d42ac7f2a7d650125d0cd7a79631c4522edaf (diff) |
firewire: ohci: lazy bus time initialization
The Bus_Time CSR is virtually never used, so we can avoid burning CPU in
interrupt context for 1 or 3 IsochronousCycleTimer accesses every minute
by not tracking the bus time until the CSR is actually accessed for the
first time.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r-- | drivers/firewire/ohci.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index c1af05e834b6..1c365b827815 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -191,6 +191,7 @@ struct fw_ohci { | |||
191 | unsigned quirks; | 191 | unsigned quirks; |
192 | unsigned int pri_req_max; | 192 | unsigned int pri_req_max; |
193 | u32 bus_time; | 193 | u32 bus_time; |
194 | bool bus_time_running; | ||
194 | bool is_root; | 195 | bool is_root; |
195 | bool csr_state_setclear_abdicate; | 196 | bool csr_state_setclear_abdicate; |
196 | int n_ir; | 197 | int n_ir; |
@@ -1726,6 +1727,13 @@ static u32 update_bus_time(struct fw_ohci *ohci) | |||
1726 | { | 1727 | { |
1727 | u32 cycle_time_seconds = get_cycle_time(ohci) >> 25; | 1728 | u32 cycle_time_seconds = get_cycle_time(ohci) >> 25; |
1728 | 1729 | ||
1730 | if (unlikely(!ohci->bus_time_running)) { | ||
1731 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_cycle64Seconds); | ||
1732 | ohci->bus_time = (lower_32_bits(get_seconds()) & ~0x7f) | | ||
1733 | (cycle_time_seconds & 0x40); | ||
1734 | ohci->bus_time_running = true; | ||
1735 | } | ||
1736 | |||
1729 | if ((ohci->bus_time & 0x40) != (cycle_time_seconds & 0x40)) | 1737 | if ((ohci->bus_time & 0x40) != (cycle_time_seconds & 0x40)) |
1730 | ohci->bus_time += 0x40; | 1738 | ohci->bus_time += 0x40; |
1731 | 1739 | ||
@@ -2213,7 +2221,7 @@ static int ohci_enable(struct fw_card *card, | |||
2213 | { | 2221 | { |
2214 | struct fw_ohci *ohci = fw_ohci(card); | 2222 | struct fw_ohci *ohci = fw_ohci(card); |
2215 | struct pci_dev *dev = to_pci_dev(card->device); | 2223 | struct pci_dev *dev = to_pci_dev(card->device); |
2216 | u32 lps, seconds, version, irqs; | 2224 | u32 lps, version, irqs; |
2217 | int i, ret; | 2225 | int i, ret; |
2218 | 2226 | ||
2219 | if (software_reset(ohci)) { | 2227 | if (software_reset(ohci)) { |
@@ -2269,9 +2277,7 @@ static int ohci_enable(struct fw_card *card, | |||
2269 | (OHCI1394_MAX_PHYS_RESP_RETRIES << 8) | | 2277 | (OHCI1394_MAX_PHYS_RESP_RETRIES << 8) | |
2270 | (200 << 16)); | 2278 | (200 << 16)); |
2271 | 2279 | ||
2272 | seconds = lower_32_bits(get_seconds()); | 2280 | ohci->bus_time_running = false; |
2273 | reg_write(ohci, OHCI1394_IsochronousCycleTimer, seconds << 25); | ||
2274 | ohci->bus_time = seconds & ~0x3f; | ||
2275 | 2281 | ||
2276 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | 2282 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; |
2277 | if (version >= OHCI_VERSION_1_1) { | 2283 | if (version >= OHCI_VERSION_1_1) { |
@@ -2369,7 +2375,6 @@ static int ohci_enable(struct fw_card *card, | |||
2369 | OHCI1394_postedWriteErr | | 2375 | OHCI1394_postedWriteErr | |
2370 | OHCI1394_selfIDComplete | | 2376 | OHCI1394_selfIDComplete | |
2371 | OHCI1394_regAccessFail | | 2377 | OHCI1394_regAccessFail | |
2372 | OHCI1394_cycle64Seconds | | ||
2373 | OHCI1394_cycleInconsistent | | 2378 | OHCI1394_cycleInconsistent | |
2374 | OHCI1394_unrecoverableError | | 2379 | OHCI1394_unrecoverableError | |
2375 | OHCI1394_cycleTooLong | | 2380 | OHCI1394_cycleTooLong | |
@@ -2658,7 +2663,8 @@ static void ohci_write_csr(struct fw_card *card, int csr_offset, u32 value) | |||
2658 | 2663 | ||
2659 | case CSR_BUS_TIME: | 2664 | case CSR_BUS_TIME: |
2660 | spin_lock_irqsave(&ohci->lock, flags); | 2665 | spin_lock_irqsave(&ohci->lock, flags); |
2661 | ohci->bus_time = (ohci->bus_time & 0x7f) | (value & ~0x7f); | 2666 | ohci->bus_time = (update_bus_time(ohci) & 0x40) | |
2667 | (value & ~0x7f); | ||
2662 | spin_unlock_irqrestore(&ohci->lock, flags); | 2668 | spin_unlock_irqrestore(&ohci->lock, flags); |
2663 | break; | 2669 | break; |
2664 | 2670 | ||