aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/ohci.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2012-05-24 13:29:19 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2012-05-27 06:31:11 -0400
commit9d60ef2bd87f201c509cfae13ba6c9013446673d (patch)
tree76c4c28d674d33c924f638cde404bfafede88e15 /drivers/firewire/ohci.c
parentf07d42ac7f2a7d650125d0cd7a79631c4522edaf (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.c18
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