]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - drivers/firewire/ohci.c
firewire: ohci: lazy bus time initialization
[linux-imx.git] / drivers / firewire / ohci.c
index 2b5460075a9fc47a84c9f0a79a06c15519a976b9..1c365b82781509fc35891d384d07ffdd45633526 100644 (file)
@@ -191,6 +191,7 @@ struct fw_ohci {
        unsigned quirks;
        unsigned int pri_req_max;
        u32 bus_time;
+       bool bus_time_running;
        bool is_root;
        bool csr_state_setclear_abdicate;
        int n_ir;
@@ -1726,6 +1727,13 @@ static u32 update_bus_time(struct fw_ohci *ohci)
 {
        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))
                ohci->bus_time += 0x40;
 
@@ -1821,9 +1829,8 @@ static void bus_reset_work(struct work_struct *work)
 {
        struct fw_ohci *ohci =
                container_of(work, struct fw_ohci, bus_reset_work);
-       int self_id_count, i, j, reg;
-       int generation, new_generation;
-       unsigned long flags;
+       int self_id_count, generation, new_generation, i, j;
+       u32 reg;
        void *free_rom = NULL;
        dma_addr_t free_rom_bus = 0;
        bool is_new_root;
@@ -1930,13 +1937,13 @@ static void bus_reset_work(struct work_struct *work)
        }
 
        /* FIXME: Document how the locking works. */
-       spin_lock_irqsave(&ohci->lock, flags);
+       spin_lock_irq(&ohci->lock);
 
        ohci->generation = -1; /* prevent AT packet queueing */
        context_stop(&ohci->at_request_ctx);
        context_stop(&ohci->at_response_ctx);
 
-       spin_unlock_irqrestore(&ohci->lock, flags);
+       spin_unlock_irq(&ohci->lock);
 
        /*
         * Per OHCI 1.2 draft, clause 7.2.3.3, hardware may leave unsent
@@ -1946,7 +1953,7 @@ static void bus_reset_work(struct work_struct *work)
        at_context_flush(&ohci->at_request_ctx);
        at_context_flush(&ohci->at_response_ctx);
 
-       spin_lock_irqsave(&ohci->lock, flags);
+       spin_lock_irq(&ohci->lock);
 
        ohci->generation = generation;
        reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
@@ -1990,7 +1997,7 @@ static void bus_reset_work(struct work_struct *work)
        reg_write(ohci, OHCI1394_PhyReqFilterLoSet, ~0);
 #endif
 
-       spin_unlock_irqrestore(&ohci->lock, flags);
+       spin_unlock_irq(&ohci->lock);
 
        if (free_rom)
                dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
@@ -2214,7 +2221,7 @@ static int ohci_enable(struct fw_card *card,
 {
        struct fw_ohci *ohci = fw_ohci(card);
        struct pci_dev *dev = to_pci_dev(card->device);
-       u32 lps, seconds, version, irqs;
+       u32 lps, version, irqs;
        int i, ret;
 
        if (software_reset(ohci)) {
@@ -2270,9 +2277,7 @@ static int ohci_enable(struct fw_card *card,
                  (OHCI1394_MAX_PHYS_RESP_RETRIES << 8) |
                  (200 << 16));
 
-       seconds = lower_32_bits(get_seconds());
-       reg_write(ohci, OHCI1394_IsochronousCycleTimer, seconds << 25);
-       ohci->bus_time = seconds & ~0x3f;
+       ohci->bus_time_running = false;
 
        version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
        if (version >= OHCI_VERSION_1_1) {
@@ -2370,7 +2375,6 @@ static int ohci_enable(struct fw_card *card,
                OHCI1394_postedWriteErr |
                OHCI1394_selfIDComplete |
                OHCI1394_regAccessFail |
-               OHCI1394_cycle64Seconds |
                OHCI1394_cycleInconsistent |
                OHCI1394_unrecoverableError |
                OHCI1394_cycleTooLong |
@@ -2402,7 +2406,6 @@ static int ohci_set_config_rom(struct fw_card *card,
                               const __be32 *config_rom, size_t length)
 {
        struct fw_ohci *ohci;
-       unsigned long flags;
        __be32 *next_config_rom;
        dma_addr_t uninitialized_var(next_config_rom_bus);
 
@@ -2441,7 +2444,7 @@ static int ohci_set_config_rom(struct fw_card *card,
        if (next_config_rom == NULL)
                return -ENOMEM;
 
-       spin_lock_irqsave(&ohci->lock, flags);
+       spin_lock_irq(&ohci->lock);
 
        /*
         * If there is not an already pending config_rom update,
@@ -2467,7 +2470,7 @@ static int ohci_set_config_rom(struct fw_card *card,
 
        reg_write(ohci, OHCI1394_ConfigROMmap, ohci->next_config_rom_bus);
 
-       spin_unlock_irqrestore(&ohci->lock, flags);
+       spin_unlock_irq(&ohci->lock);
 
        /* If we didn't use the DMA allocation, delete it. */
        if (next_config_rom != NULL)
@@ -2660,7 +2663,8 @@ static void ohci_write_csr(struct fw_card *card, int csr_offset, u32 value)
 
        case CSR_BUS_TIME:
                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);
                break;
 
@@ -2891,10 +2895,9 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
        descriptor_callback_t uninitialized_var(callback);
        u64 *uninitialized_var(channels);
        u32 *uninitialized_var(mask), uninitialized_var(regs);
-       unsigned long flags;
        int index, ret = -EBUSY;
 
-       spin_lock_irqsave(&ohci->lock, flags);
+       spin_lock_irq(&ohci->lock);
 
        switch (type) {
        case FW_ISO_CONTEXT_TRANSMIT:
@@ -2938,7 +2941,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
                ret = -ENOSYS;
        }
 
-       spin_unlock_irqrestore(&ohci->lock, flags);
+       spin_unlock_irq(&ohci->lock);
 
        if (index < 0)
                return ERR_PTR(ret);
@@ -2964,7 +2967,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
  out_with_header:
        free_page((unsigned long)ctx->header);
  out:
-       spin_lock_irqsave(&ohci->lock, flags);
+       spin_lock_irq(&ohci->lock);
 
        switch (type) {
        case FW_ISO_CONTEXT_RECEIVE:
@@ -2977,7 +2980,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
        }
        *mask |= 1 << index;
 
-       spin_unlock_irqrestore(&ohci->lock, flags);
+       spin_unlock_irq(&ohci->lock);
 
        return ERR_PTR(ret);
 }
@@ -3789,6 +3792,8 @@ static struct pci_driver fw_ohci_pci_driver = {
 #endif
 };
 
+module_pci_driver(fw_ohci_pci_driver);
+
 MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
 MODULE_DESCRIPTION("Driver for PCI OHCI IEEE1394 controllers");
 MODULE_LICENSE("GPL");
@@ -3797,16 +3802,3 @@ MODULE_LICENSE("GPL");
 #ifndef CONFIG_IEEE1394_OHCI1394_MODULE
 MODULE_ALIAS("ohci1394");
 #endif
-
-static int __init fw_ohci_init(void)
-{
-       return pci_register_driver(&fw_ohci_pci_driver);
-}
-
-static void __exit fw_ohci_cleanup(void)
-{
-       pci_unregister_driver(&fw_ohci_pci_driver);
-}
-
-module_init(fw_ohci_init);
-module_exit(fw_ohci_cleanup);