提交 9d60ef2b 编写于 作者: C Clemens Ladisch 提交者: Stefan Richter

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: NClemens Ladisch <clemens@ladisch.de>
Signed-off-by: NStefan Richter <stefanr@s5r6.in-berlin.de>
上级 f07d42ac
...@@ -191,6 +191,7 @@ struct fw_ohci { ...@@ -191,6 +191,7 @@ struct fw_ohci {
unsigned quirks; unsigned quirks;
unsigned int pri_req_max; unsigned int pri_req_max;
u32 bus_time; u32 bus_time;
bool bus_time_running;
bool is_root; bool is_root;
bool csr_state_setclear_abdicate; bool csr_state_setclear_abdicate;
int n_ir; int n_ir;
...@@ -1726,6 +1727,13 @@ static u32 update_bus_time(struct fw_ohci *ohci) ...@@ -1726,6 +1727,13 @@ static u32 update_bus_time(struct fw_ohci *ohci)
{ {
u32 cycle_time_seconds = get_cycle_time(ohci) >> 25; u32 cycle_time_seconds = get_cycle_time(ohci) >> 25;
if (unlikely(!ohci->bus_time_running)) {
reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_cycle64Seconds);
ohci->bus_time = (lower_32_bits(get_seconds()) & ~0x7f) |
(cycle_time_seconds & 0x40);
ohci->bus_time_running = true;
}
if ((ohci->bus_time & 0x40) != (cycle_time_seconds & 0x40)) if ((ohci->bus_time & 0x40) != (cycle_time_seconds & 0x40))
ohci->bus_time += 0x40; ohci->bus_time += 0x40;
...@@ -2213,7 +2221,7 @@ static int ohci_enable(struct fw_card *card, ...@@ -2213,7 +2221,7 @@ static int ohci_enable(struct fw_card *card,
{ {
struct fw_ohci *ohci = fw_ohci(card); struct fw_ohci *ohci = fw_ohci(card);
struct pci_dev *dev = to_pci_dev(card->device); struct pci_dev *dev = to_pci_dev(card->device);
u32 lps, seconds, version, irqs; u32 lps, version, irqs;
int i, ret; int i, ret;
if (software_reset(ohci)) { if (software_reset(ohci)) {
...@@ -2269,9 +2277,7 @@ static int ohci_enable(struct fw_card *card, ...@@ -2269,9 +2277,7 @@ static int ohci_enable(struct fw_card *card,
(OHCI1394_MAX_PHYS_RESP_RETRIES << 8) | (OHCI1394_MAX_PHYS_RESP_RETRIES << 8) |
(200 << 16)); (200 << 16));
seconds = lower_32_bits(get_seconds()); ohci->bus_time_running = false;
reg_write(ohci, OHCI1394_IsochronousCycleTimer, seconds << 25);
ohci->bus_time = seconds & ~0x3f;
version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
if (version >= OHCI_VERSION_1_1) { if (version >= OHCI_VERSION_1_1) {
...@@ -2369,7 +2375,6 @@ static int ohci_enable(struct fw_card *card, ...@@ -2369,7 +2375,6 @@ static int ohci_enable(struct fw_card *card,
OHCI1394_postedWriteErr | OHCI1394_postedWriteErr |
OHCI1394_selfIDComplete | OHCI1394_selfIDComplete |
OHCI1394_regAccessFail | OHCI1394_regAccessFail |
OHCI1394_cycle64Seconds |
OHCI1394_cycleInconsistent | OHCI1394_cycleInconsistent |
OHCI1394_unrecoverableError | OHCI1394_unrecoverableError |
OHCI1394_cycleTooLong | OHCI1394_cycleTooLong |
...@@ -2658,7 +2663,8 @@ static void ohci_write_csr(struct fw_card *card, int csr_offset, u32 value) ...@@ -2658,7 +2663,8 @@ static void ohci_write_csr(struct fw_card *card, int csr_offset, u32 value)
case CSR_BUS_TIME: case CSR_BUS_TIME:
spin_lock_irqsave(&ohci->lock, flags); spin_lock_irqsave(&ohci->lock, flags);
ohci->bus_time = (ohci->bus_time & 0x7f) | (value & ~0x7f); ohci->bus_time = (update_bus_time(ohci) & 0x40) |
(value & ~0x7f);
spin_unlock_irqrestore(&ohci->lock, flags); spin_unlock_irqrestore(&ohci->lock, flags);
break; break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册